]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/refptr.h
Assimilate exceptions and RefPtr from mspmisc
[libs/core.git] / source / core / refptr.h
diff --git a/source/core/refptr.h b/source/core/refptr.h
new file mode 100644 (file)
index 0000000..ee020e0
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id$
+
+This file is part of libmspcore
+Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+#ifndef MSP_CORE_REFPTR_H_
+#define MSP_CORE_REFPTR_H_
+
+namespace Msp {
+
+template<typename T>
+class RefPtr
+{
+public:
+       RefPtr(): data(0), count(0) { }
+       RefPtr(T *d): data(d), count(0) { if(data) count=new unsigned(1); }
+       RefPtr(const RefPtr &p): data(p.data), count(p.count) { incref(); }
+       ~RefPtr() { decref(); }
+
+       RefPtr &operator=(const RefPtr &p)
+       {
+               decref();
+               data=p.data;
+               count=p.count;
+               incref();
+               return *this;
+       }
+
+       T *get() const        { return data; }
+       T &operator*() const  { return *data; }
+       T *operator->() const { return data; }
+       operator bool() const { return data!=0; }
+
+       template<typename U>
+       static RefPtr<T> cast_dynamic(const RefPtr<U> &p)  { return RefPtr<T>(dynamic_cast<T *>(p.get()), p.count); }
+       template<typename U> friend class RefPtr;
+private:
+       T        *data;
+       unsigned *count;
+
+       RefPtr(T *d, unsigned *c): data(d), count(c) { incref(); }
+
+       void  incref()
+       {
+               if(!count) return;
+               ++*count;
+       }
+
+       void  decref()
+       {
+               if(!count) return;
+               --*count;
+               if(!*count)
+               {
+                       delete data;
+                       delete count;
+                       data=0;
+                       count=0;
+               }
+       }
+};
+
+} // namespace Msp
+
+#endif