summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-07-20 18:44:04 +0000
committerrubidium <rubidium@openttd.org>2007-07-20 18:44:04 +0000
commit5083f22d1ddddd355d75a3d720fc2f5a3acd12a5 (patch)
tree5f1f70f105e1d48e5c98012e8393a7374f6668e7 /src/misc
parent3f983ff1f227420eed715f4333a3055e9196eeef (diff)
downloadopenttd-5083f22d1ddddd355d75a3d720fc2f5a3acd12a5.tar.xz
(svn r10644) -Merge (from NoAI): framework for reference counted objects (pointers).
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/autoptr.hpp3
-rw-r--r--src/misc/countedobj.cpp66
-rw-r--r--src/misc/countedptr.hpp72
3 files changed, 133 insertions, 8 deletions
diff --git a/src/misc/autoptr.hpp b/src/misc/autoptr.hpp
index 08516d2ea..3719a51f1 100644
--- a/src/misc/autoptr.hpp
+++ b/src/misc/autoptr.hpp
@@ -38,8 +38,9 @@ public:
FORCEINLINE ~AutoPtrT()
{
if (m_p != NULL) {
- delete m_p;
+ T *p = m_p;
m_p = NULL;
+ delete p;
}
}
diff --git a/src/misc/countedobj.cpp b/src/misc/countedobj.cpp
new file mode 100644
index 000000000..a96537977
--- /dev/null
+++ b/src/misc/countedobj.cpp
@@ -0,0 +1,66 @@
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "countedptr.hpp"
+
+int32 SimpleCountedObject::AddRef()
+{
+ return ++m_ref_cnt;
+}
+
+int32 SimpleCountedObject::Release()
+{
+ int32 res = --m_ref_cnt;
+ assert(res >= 0);
+ if (res == 0) {
+ FinalRelease();
+ delete this;
+ }
+ return res;
+}
+
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "countedptr.hpp"
+
+int32 SimpleCountedObject::AddRef()
+{
+ return ++m_ref_cnt;
+}
+
+int32 SimpleCountedObject::Release()
+{
+ int32 res = --m_ref_cnt;
+ assert(res >= 0);
+ if (res == 0) {
+ FinalRelease();
+ delete this;
+ }
+ return res;
+}
+
+/* $Id$ */
+
+#include "../stdafx.h"
+
+#include "countedptr.hpp"
+
+int32 SimpleCountedObject::AddRef()
+{
+ return ++m_ref_cnt;
+}
+
+int32 SimpleCountedObject::Release()
+{
+ int32 res = --m_ref_cnt;
+ assert(res >= 0);
+ if (res == 0) {
+ FinalRelease();
+ delete this;
+ }
+ return res;
+}
+
diff --git a/src/misc/countedptr.hpp b/src/misc/countedptr.hpp
index 0d6a925b8..e3920e49a 100644
--- a/src/misc/countedptr.hpp
+++ b/src/misc/countedptr.hpp
@@ -5,7 +5,6 @@
#ifndef COUNTEDPTR_HPP
#define COUNTEDPTR_HPP
-#if 0 // reenable when needed
/** @file CCountedPtr - smart pointer implementation */
/** CCountedPtr - simple reference counting smart pointer.
@@ -44,7 +43,7 @@ protected:
public:
/** release smart pointer (and decrement ref count) if not null */
- FORCEINLINE void Release() {if (m_pT != NULL) {m_pT->Release(); m_pT = NULL;}}
+ FORCEINLINE void Release() {if (m_pT != NULL) {Tcls* pT = m_pT; m_pT = NULL; pT->Release();}}
/** dereference of smart pointer - const way */
FORCEINLINE const Tcls* operator -> () const {assert(m_pT != NULL); return m_pT;};
@@ -56,7 +55,7 @@ public:
FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;}
/** raw pointer casting operator - non-const way */
- FORCEINLINE operator Tcls*() {assert(m_pT == NULL); return m_pT;}
+ FORCEINLINE operator Tcls*() {return m_pT;}
/** operator & to support output arguments */
FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;}
@@ -65,7 +64,7 @@ public:
FORCEINLINE CCountedPtr& operator = (Tcls* pT) {Assign(pT); return *this;}
/** assignment operator from another smart ptr */
- FORCEINLINE CCountedPtr& operator = (CCountedPtr& src) {Assign(src.m_pT); return *this;}
+ FORCEINLINE CCountedPtr& operator = (const CCountedPtr& src) {Assign(src.m_pT); return *this;}
/** assignment operator helper */
FORCEINLINE void Assign(Tcls* pT);
@@ -74,10 +73,10 @@ public:
FORCEINLINE bool IsNull() const {return m_pT == NULL;}
/** another way how to test for NULL value */
- FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;}
+ //FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;}
/** yet another way how to test for NULL value */
- FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;}
+ //FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;}
/** assign pointer w/o incrementing ref count */
FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;}
@@ -98,5 +97,64 @@ FORCEINLINE void CCountedPtr<Tcls_>::Assign(Tcls* pT)
}
}
-#endif /* 0 */
+/**
+ * Adapter wrapper for CCountedPtr like classes that can't be used directly by stl
+ * collections as item type. For example CCountedPtr has overloaded operator & which
+ * prevents using CCountedPtr in stl collections (i.e. std::list<CCountedPtr<MyType> >)
+ */
+template <class T> struct AdaptT {
+ T m_t;
+
+ /** construct by wrapping the given object */
+ AdaptT(const T &t)
+ : m_t(t)
+ {}
+
+ /** assignment operator */
+ T& operator = (const T &t)
+ {
+ m_t = t;
+ return t;
+ }
+
+ /** type-cast operator (used when AdaptT is used instead of T) */
+ operator T& ()
+ {
+ return m_t;
+ }
+
+ /** const type-cast operator (used when AdaptT is used instead of const T) */
+ operator const T& () const
+ {
+ return m_t;
+ }
+};
+
+
+/** Simple counted object. Use it as base of your struct/class if you want to use
+ * basic reference counting. Your struct/class will destroy and free itself when
+ * last reference to it is released (using Relese() method). The initial reference
+ * count (when it is created) is zero (don't forget AddRef() at least one time if
+ * not using CCountedPtr<T>.
+ *
+ * @see misc/countedobj.cpp for implementation.
+ */
+struct SimpleCountedObject {
+ int32 m_ref_cnt;
+
+ SimpleCountedObject()
+ : m_ref_cnt(0)
+ {}
+
+ virtual ~SimpleCountedObject()
+ {};
+
+ virtual int32 AddRef();
+ virtual int32 Release();
+ virtual void FinalRelease() {};
+};
+
+
+
+
#endif /* COUNTEDPTR_HPP */