//
//  Copyright © 2003, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   Singleton.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines and implements the template class CSingleton.
//
//  Notes:      
//

#if !defined(AFX_7KSUBSYSTEM_H__BA56BAA6_00BC_4748_801D_4537C58BC877__INCLUDED_)
#define AFX_7KSUBSYSTEM_H__BA56BAA6_00BC_4748_801D_4537C58BC877__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

using std::auto_ptr;

template <class tContained>
class CSingleton
{
public:

    ///////////////
    // Definitions.

    typedef auto_ptr<tContained>        Singleton_t;

    ///////////////
    // Services.

                                        CSingleton          (   void );
    virtual                            ~CSingleton          (   void );

    operator                            tContained *        ()          const;                  // Access to the contained singleton's pointer.

protected:

    ///////////////
    // Services.
                                        CSingleton          (   const   CSingleton &rRhs );     // Not implemented thus private.
    CSingleton &                        operator =          (   const   CSingleton &rRhs );     // Not implemented thus private.

    ///////////////
    // Attributes.

    static int                          m_iReferenceCount;
    static Singleton_t                  m_Singleton;

};

///////////////////////////////////////////////////////////////////////////////
// Static member initialisation.

template <class tContained> CSingleton<tContained>::Singleton_t CSingleton<tContained>::m_Singleton;
template <class tContained> int                                 CSingleton<tContained>::m_iReferenceCount = 0;

///////////////////////////////////////////////////////////////////////////////
// CSingleton class implementation.

template <class tContained>
CSingleton<tContained>::CSingleton( void )
{
    if ( ( ++m_iReferenceCount > 0 ) && ( m_Singleton.get() == NULL ) )
    {
        m_Singleton = Singleton_t( new tContained );
    }

    ASSERT( m_iReferenceCount >  0 );
    ASSERT( m_Singleton.get() != NULL );
}

template <class tContained>
CSingleton<tContained>::~CSingleton( void )
{
    if ( --m_iReferenceCount <= 0 )
    {
        m_iReferenceCount = 0;

        if ( m_Singleton.get() != NULL )
        {
            delete ( m_Singleton.release() );
            m_Singleton = Singleton_t( NULL );
        }
    }
}

template <class tContained>
CSingleton<tContained>::operator tContained *() const
{
    return ( static_cast<tContained *>( m_Singleton.get() ) );
}

#endif  // !defined(AFX_7KSUBSYSTEM_H__BA56BAA6_00BC_4748_801D_4537C58BC877__INCLUDED_)
