summaryrefslogtreecommitdiff
path: root/src/reference.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/reference.h')
-rw-r--r--src/reference.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/reference.h b/src/reference.h
new file mode 100644
index 0000000..8b82a61
--- /dev/null
+++ b/src/reference.h
@@ -0,0 +1,112 @@
+#ifndef __REFERENCE_H__
+#define __REFERENCE_H__
+
+template<typename C>
+class Reference
+{
+public:
+ Reference()
+ { m_ptr = NULL; }
+
+ Reference(C* ptr)
+ {
+ m_ptr = ptr;
+ addref();
+ }
+
+ Reference(C* ptr, bool addref)
+ {
+ m_ptr = ptr;
+ if(addref)
+ addref();
+ }
+
+ ~Reference()
+ {
+ release();
+ }
+
+ Reference(const Reference& orig)
+ {
+ m_ptr = orig.m_ptr;
+ addref();
+ }
+
+ Reference& operator=(const C* ptr)
+ {
+ C* old = m_ptr;
+ m_ptr = (C*)ptr;
+ addref();
+ if(old)
+ old->release();
+ return *this;
+ }
+
+ Reference& operator=(const Reference& orig)
+ { return operator=(orig.m_ptr); }
+
+ void attach(C* ptr)
+ {
+ release();
+ m_ptr = ptr;
+ }
+
+ C* detach()
+ {
+ C* ptr = m_ptr;
+ m_ptr = NULL;
+ return ptr;
+ }
+
+ operator C*() const
+ { return m_ptr; }
+
+ C* operator->() const
+ { return m_ptr; }
+
+#if 0
+ operator bool() const
+ {
+ return m_ptr != NULL;
+ }
+#endif
+
+ void release()
+ {
+ if(m_ptr)
+ m_ptr->release();
+ m_ptr = NULL;
+ }
+
+ void addref()
+ {
+ if(m_ptr)
+ m_ptr->addRef();
+ }
+
+private:
+ C* m_ptr;
+};
+
+class Instance
+{
+public:
+ Instance()
+ { m_x = 0; }
+ virtual ~Instance()
+ { }
+ void addRef()
+ { m_x++; }
+ void release()
+ {
+ if((--m_x) <= 0)
+ delete this;
+ }
+
+private:
+ // The reference count
+ int m_x;
+};
+
+
+#endif //__REFERENCE_H__ \ No newline at end of file