You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmplayer/src/kmplayershared.h

265 lines
8.8 KiB

/* This file is part of the KDE project
*
* Copyright (C) 2004 Koos Vriezen <koos.vriezen@xs4all.nl>
*
* 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