/*
 * Copyright (c) 1999 Johnny C. Lam.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  The author makes no representations
 * about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 */

#ifndef DP_INTERNAL_SINGLETON_H
#define DP_INTERNAL_SINGLETON_H

/*
 * This file implements Singleton<T>, which follows the design pattern
 * "Singleton".
 */

template <class Doomed>
class SingletonDestroyer {
public:
    SingletonDestroyer(Doomed* = 0);
    ~SingletonDestroyer();

    void SetDoomed(Doomed*);

private:
    /* Prevent users from making copies to avoid double deletion. */
    SingletonDestroyer(const SingletonDestroyer<Doomed> &);
    SingletonDestroyer<Doomed> & operator=(SingletonDestroyer<Doomed> &);

private:
    Doomed *_doomed;
};

/*
 * T must inherit from Singleton<T>.
 */

template <class T>
class Singleton {
public:
    static T* Instance();
    
protected:
    Singleton() {}

    friend class SingletonDestroyer<Singleton<T> >;
    virtual ~Singleton() {}

private:
    static T* _instance;
    static SingletonDestroyer<Singleton<T> > _destroyer;
};

#define INITIALIZE_SINGLETON_BASE(T) \
	T* Singleton<T>::_instance = 0; \
	SingletonDestroyer<Singleton<T> > Singleton<T>::_destroyer

#include <dp_singleton_inline.h>

#endif /* DP_INTERNAL_SINGLETON_H */
