/****************************************************************************
**
** Copyright (C) 1992-2004 Trolltech AS. All rights reserved.
**
** This file is part of the core module of the Qt Toolkit.
**
** Licensees holding valid Qt Preview licenses may use this file in
** accordance with the Qt Preview License Agreement provided with the
** Software.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#ifndef QCLEANUPHANDLER_H
#define QCLEANUPHANDLER_H

#include <qlist.h>

template<class T>
class QCleanupHandler
{
    QListData p;
public:
    inline QCleanupHandler()
    { p.d = 0; }
    ~QCleanupHandler()
    {
        if (p.d) {
            for (int i = 0; i < p.size(); ++i) {
                T** t = static_cast<T**>(*p.at(i));
                delete *t;
                *t = 0;
            }
            qFree(p.d);
            p.d = 0;
        }
    }

    T* add(T **object)
    {
        if (!p.d) {
            p.d = &QListData::shared_null;
            ++p.d->ref;
            p.detach();
        }
        *p.prepend() =  object;
        return *object;
    }
    void remove(T **object)
    {
        if (p.d)
            for (int i = 0; i < p.size(); ++i)
                if (*p.at(i) == object)
                    p.remove(i--);
    }
};

template<class T>
class QSingleCleanupHandler
{
    T **object;
public:
    inline QSingleCleanupHandler()
    : object(0) {}
    inline ~QSingleCleanupHandler()
    { if (object) { delete *object; *object = 0; } }
    inline T* set(T **o)
    { object = o; return *object; }
    inline void reset() { object = 0; }
};


// ###### remove before release!
template<class T>
class QSharedCleanupHandler
{
    T **object;
public:
    inline QSharedCleanupHandler() : object(0) {}
    inline ~QSharedCleanupHandler()
    {
        if (object) {
            if ((*object)->deref()) delete *object;
            *object = 0;
        }
    }
    inline T* set(T **o) { object = o; return *object; }
    inline void reset() { object = 0; }
};

#endif //QCLEANUPHANDLER_H
