summaryrefslogtreecommitdiffstats
path: root/src/kmplayershared.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/kmplayershared.h')
-rw-r--r--src/kmplayershared.h264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/kmplayershared.h b/src/kmplayershared.h
new file mode 100644
index 0000000..3066b4c
--- /dev/null
+++ b/src/kmplayershared.h
@@ -0,0 +1,264 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2004 Koos Vriezen <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * until boost gets common, a more or less compatable one ..
+ */
+
+#ifndef _SHAREDPTR_H_
+#define _SHAREDPTR_H_
+
+//#define SHAREDPTR_DEBUG
+
+#ifdef SHAREDPTR_DEBUG
+extern int shared_data_count;
+#include <iostream>
+#endif
+
+namespace KMPlayer {
+
+/**
+ * Shared data for SharedPtr and WeakPtr objects.
+ **/
+template <class T>
+struct SharedData {
+ SharedData (T * t, bool w) : use_count (w?0:1), weak_count (1), ptr (t) {
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::SharedData use:" << use_count << " weak:" << weak_count << " total:" << ++shared_data_count << std::endl;
+#endif
+ }
+#ifdef SHAREDPTR_DEBUG
+ ~SharedData () { std::cerr << "SharedData::~SharedData" << " total:" << --shared_data_count << std::endl; }
+#endif
+ void addRef ();
+ void addWeakRef ();
+ void release ();
+ void releaseWeak ();
+ void dispose ();
+ int use_count;
+ int weak_count;
+ T * ptr;
+};
+
+template <class T> inline void SharedData<T>::addRef () {
+ use_count++;
+ weak_count++;
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::addRef use:" << use_count << " weak:" << weak_count << std::endl;
+#endif
+}
+
+template <class T> inline void SharedData<T>::addWeakRef () {
+ weak_count++;
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::addWeakRef use:" << use_count << " weak:" << weak_count << std::endl;
+#endif
+}
+
+template <class T> inline void SharedData<T>::releaseWeak () {
+ ASSERT (weak_count > 0 && weak_count > use_count);
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::releaseWeak use:" << use_count << " weak:" << weak_count-1 << std::endl;
+#endif
+ if (--weak_count <= 0) delete this;
+}
+
+template <class T> inline void SharedData<T>::release () {
+ ASSERT (use_count > 0);
+ if (--use_count <= 0) dispose ();
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::release use:" << use_count << " weak:" << weak_count << std::endl;
+#endif
+ releaseWeak ();
+}
+
+template <class T> inline void SharedData<T>::dispose () {
+ ASSERT (use_count == 0);
+#ifdef SHAREDPTR_DEBUG
+ std::cerr << "SharedData::dispose use:" << use_count << " weak:" << weak_count << std::endl;
+#endif
+ delete ptr;
+ ptr = 0;
+}
+
+template <class T> struct WeakPtr;
+
+/**
+ * Shared class based on boost shared
+ * This makes it possible to share pointers w/o having to worry about
+ * memory leaks. A pointer gets deleted as soon as the last Shared pointer
+ * gets destroyed. As such, never use (or be extremely carefull) not to
+ * use pointers or references to shared objects
+ **/
+template <class T>
+struct SharedPtr {
+ SharedPtr () : data (0L) {};
+ SharedPtr (T *t) : data (t ? new SharedData<T> (t, false) : 0L) {}
+ SharedPtr (const SharedPtr<T> & s) : data (s.data) { if (data) data->addRef (); }
+ SharedPtr (const WeakPtr <T> &);
+ ~SharedPtr () { if (data) data->release (); }
+ SharedPtr<T> & operator = (const SharedPtr<T> &);
+ SharedPtr<T> & operator = (const WeakPtr<T> &);
+ SharedPtr<T> & operator = (T *);
+ T * ptr () const { return data ? data->ptr : 0L; }
+ T * operator -> () { return data ? data->ptr : 0L; }
+ T * operator -> () const { return data ? data->ptr : 0L; }
+ T & operator * () { return *data->ptr; }
+ const T & operator * () const { return *data->ptr; }
+ // operator bool () const { return data && data->ptr; }
+ bool operator == (const SharedPtr<T> & s) const { return data == s.data; }
+ bool operator == (const WeakPtr<T> & w) const;
+ bool operator == (const T * t) const { return (!t && !data) || (data && data->ptr == t); }
+ bool operator == (T * t) const { return (!t && !data) || (data && data->ptr == t); }
+ bool operator != (const SharedPtr<T> & s) const { return data != s.data; }
+ bool operator != (const WeakPtr<T> & w) const;
+ bool operator != (const T * t) const { return !operator == (t); }
+ operator T * () { return data ? data->ptr : 0L; }
+ operator const T * () const { return data ? data->ptr : 0L; }
+ mutable SharedData<T> * data;
+};
+
+template <class T>
+bool operator == (T * t, SharedPtr <T> & s) {
+ return (!t && !s.data) || (s.data && s.data->ptr == t);
+}
+
+template <class T>
+bool operator == (const T * t, SharedPtr <T> & s) {
+ return (!t && !s.data) || (s.data && s.data->ptr == t);
+}
+
+template <class T>
+inline SharedPtr<T> & SharedPtr<T>::operator = (const SharedPtr<T> & s) {
+ if (data != s.data) {
+ SharedData<T> * tmp = data;
+ data = s.data;
+ if (data) data->addRef ();
+ if (tmp) tmp->release ();
+ }
+ return *this;
+}
+
+template <class T> inline SharedPtr<T> & SharedPtr<T>::operator = (T * t) {
+ if ((!data && t) || (data && data->ptr != t)) {
+ if (data) data->release ();
+ data = t ? new SharedData<T> (t, false) : 0L;
+ }
+ return *this;
+}
+
+/**
+ * Weak version of SharedPtr. This will also have access to the SharedData
+ * pointer, only these object wont prevent destruction of the shared
+ * pointer, hence weak references
+ */
+template <class T>
+struct WeakPtr {
+ WeakPtr () : data (0L) {};
+ WeakPtr (T * t) : data (t ? new SharedData<T> (t, true) : 0) {}
+ WeakPtr (T * t, bool /*b*/) : data (t ? new SharedData<T> (t, true) : 0) {}
+ WeakPtr (const WeakPtr<T> & s) : data (s.data) { if (data) data->addWeakRef (); }
+ WeakPtr (const SharedPtr<T> & s) : data (s.data) { if (data) data->addWeakRef (); }
+ ~WeakPtr () { if (data) data->releaseWeak (); }
+ WeakPtr<T> & operator = (const WeakPtr<T> &);
+ WeakPtr<T> & operator = (const SharedPtr<T> &);
+ WeakPtr<T> & operator = (T *);
+ T * ptr () const { return data ? data->ptr : 0L; }
+ T * operator -> () { return data ? data->ptr : 0L; }
+ const T * operator -> () const { return data ? data->ptr : 0L; }
+ T & operator * () { return *data->ptr; }
+ const T & operator * () const { return *data->ptr; }
+ // operator bool () const { return data && !!data->ptr; }
+ bool operator == (const WeakPtr<T> & w) const { return data == w.data; }
+ bool operator == (const SharedPtr<T> & s) const { return data == s.data; }
+ bool operator == (const T * t) const { return (!t && !data) || (data && data.ptr == t); }
+ bool operator == (T * t) const { return (!t && !data) || (data && data.ptr == t); }
+ bool operator != (const WeakPtr<T> & w) const { return data != w.data; }
+ bool operator != (const SharedPtr<T> & s) const { return data != s.data; }
+ operator T * () { return data ? data->ptr : 0L; }
+ operator const T * () const { return data ? data->ptr : 0L; }
+ mutable SharedData<T> * data;
+};
+
+template <class T>
+bool operator == (T * t, WeakPtr <T> & s) {
+ return (!t && !s.data) || (s.data && s.data->ptr == t);
+}
+
+template <class T>
+bool operator == (const T * t, WeakPtr <T> & s) {
+ return (!t && !s.data) || (s.data && s.data->ptr == t);
+}
+
+template <class T>
+inline WeakPtr<T> & WeakPtr<T>::operator = (const WeakPtr<T> & w) {
+ if (data != w.data) {
+ SharedData<T> * tmp = data;
+ data = w.data;
+ if (data) data->addWeakRef ();
+ if (tmp) tmp->releaseWeak ();
+ }
+ return *this;
+}
+
+template <class T>
+inline WeakPtr<T> & WeakPtr<T>::operator = (const SharedPtr<T> & s) {
+ if (data != s.data) {
+ SharedData<T> * tmp = data;
+ data = s.data;
+ if (data) data->addWeakRef ();
+ if (tmp) tmp->releaseWeak ();
+ }
+ return *this;
+}
+
+template <class T>
+inline WeakPtr<T> & WeakPtr<T>::operator = (T * t) {
+ if (data) data->releaseWeak ();
+ data = t ? new SharedData<T> (t, true) : 0L;
+ return *this;
+}
+
+template <class T> inline SharedPtr<T>::SharedPtr (const WeakPtr <T> & w) : data (w.data) {
+ if (data) data->addRef ();
+}
+
+template <class T>
+inline SharedPtr<T> & SharedPtr<T>::operator = (const WeakPtr<T> & s) {
+ if (data != s.data) {
+ SharedData<T> * tmp = data;
+ data = s.data;
+ if (data) data->addRef ();
+ if (tmp) tmp->release ();
+ }
+ return *this;
+}
+
+template <class T>
+inline bool SharedPtr<T>::operator == (const WeakPtr<T> & w) const {
+ return data == w.data;
+}
+
+template <class T>
+inline bool SharedPtr<T>::operator != (const WeakPtr<T> & w) const {
+ return data != w.data;
+}
+
+}
+
+#endif