cpp_photon/include/util/Singleton.hpp
2005-03-03 09:25:19 +00:00

127 lines
2.6 KiB
C++

//This file is part of Photon (http://photon.sourceforge.net)
//Copyright (C) 2004-2005 James Turk
//
// Author:
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: Singleton.hpp,v 1.5 2005/03/03 09:25:20 cozman Exp $
#ifndef PHOTON_UTIL_SINGLETON_HPP
#define PHOTON_UTIL_SINGLETON_HPP
#include <memory>
#include <boost/utility.hpp>
#include "exceptions.hpp"
namespace photon
{
namespace util
{
// Class: Singleton
// Template class for singleton pattern. Is non-copyable to enforce
// correct behavior.
//
// Defining a Singleton:
// (code)
// YourClass : public Singleton<Class>
// {
// // class specific data
//
// // Singleton-required code
// private:
// // Singleton-required code
// YourClass();
// ~YourClass();
//
// friend class util::Singleton<YourClass>;
// friend class std::auto_ptr<YourClass>;
// };
// (end)
//
// Using The Singleton:
// (code)
// YourClass::initialize();
// YourClass& yc(YourClass::getInstance());
//
// // use yc
//
// YourClass::destroy(); //optional
// (end)
template<class T>
class Singleton : public boost::noncopyable
{
public:
// Function: initialize
// Initialize the instance of the singleton, must be done explicitly.
static void initialize();
// Function: destroy
// Destroy the instance of the singleton, can be done explicitly if order
// of destruction matters. Will be done automatically if not done.
static void destroy();
// Function: getInstance
// Get a reference to the instance of the derived class.
static T& getInstance();
protected:
virtual ~Singleton()=0; // allow inheritance
private:
static std::auto_ptr<T> instance_;
};
// template implementation
template<class T>
Singleton<T>::~Singleton()
{
}
template<class T>
void Singleton<T>::initialize()
{
if(instance_.get() != 0)
{
throw PreconditionException("Attempt to double-initialize singleton.");
}
instance_ = std::auto_ptr<T>(new T);
}
template<class T>
void Singleton<T>::destroy()
{
if(instance_.get() == 0)
{
throw PreconditionException("Attempt to destroy null singleton.");
}
instance_.reset();
}
template<class T>
T& Singleton<T>::getInstance()
{
if(instance_.get() == 0)
{
throw PreconditionException("Attempt to get instance of uninitialized "
"singleton.");
}
return *instance_; //return dereferenced version
}
template<class T>
std::auto_ptr<T> Singleton<T>::instance_(0);
}
}
#endif //PHOTON_UTIL_SINGLETON_HPP