/* * Singleton_impl.hpp * * Created on: Mar 10, 2010 * Author: crueger */ #ifndef SINGLETON_IMPL_HPP_ #define SINGLETON_IMPL_HPP_ #include "Helpers/Assert.hpp" #include "Patterns/Singleton.hpp" /****** Static instance Variables of the template *******/ template typename Singleton::ptr_t Singleton::theInstance(0); template boost::recursive_mutex Singleton::instanceLock; /****** templates singleton creation and destruction functions ******/ template T& Singleton::getInstance(){ // boost supports RAII-Style locking, so we don't need to unlock boost::recursive_mutex::scoped_lock guard(instanceLock); if(!theInstance.get()) { theInstance.reset(creator::make()); } return *theInstance; } template T* Singleton::getPointer(){ // boost supports RAII-Style locking, so we don't need to unlock boost::recursive_mutex::scoped_lock guard(instanceLock); if(!theInstance.get()) { theInstance.reset(creator::make()); } return theInstance.get(); } template void Singleton::purgeInstance(){ // boost supports RAII-Style locking, so we don't need to unlock boost::recursive_mutex::scoped_lock guard(instanceLock); theInstance.reset(); } template T& Singleton::resetInstance(){ ptr_t oldInstance; { // boost supports RAII-Style locking, so we don't need to unlock boost::recursive_mutex::scoped_lock guard(instanceLock); oldInstance = theInstance; theInstance.reset(creator::make()); // oldworld does not need protection any more, // since we should have the only reference // worldLock handles access to the pointer, // not to the object } // scope-end releases the lock // oldInstance goes out of scope at the End of this function. The carried object will then be destroyed by the auto_ptr return *theInstance; } template void Singleton::setInstance(T* newInstance){ ASSERT(!theInstance.get(), "Trying to set the instance of an already created singleton"); boost::recursive_mutex::scoped_lock guard(instanceLock); theInstance.reset(newInstance); } template Singleton::Singleton(){/* empty */} // private copy constructor to avoid unintended copying template Singleton::Singleton(const Singleton&){ ASSERT(0, "Copy constructor of singleton template called"); } /** * This define allows simple instantiation of the necessary singleton functions * at a chosen place. */ #define CONSTRUCT_SINGLETON(name) \ template name& Singleton< name , name::may_create >::getInstance(); \ template name* Singleton< name , name::may_create >::getPointer(); \ template void Singleton< name , name::may_create >::purgeInstance(); \ template name& Singleton< name , name::may_create >::resetInstance(); \ template void Singleton< name , name::may_create >::setInstance( name* ); /************ Internal Pointer Wrapper to allow automatic purging *************/ template Singleton::ptr_t::ptr_t() : content(0){}; template Singleton::ptr_t::ptr_t(T* _content) : content(_content){}; template Singleton::ptr_t:: ~ptr_t() {delete content;}; template T& Singleton::ptr_t::operator*() {return *content;}; template T* Singleton::ptr_t::get() {return content;}; template void Singleton::ptr_t::reset(T* _content){ delete content; content = _content; } template void Singleton::ptr_t::reset() {reset(0);} template typename Singleton::ptr_t& Singleton::ptr_t::operator=(const typename Singleton::ptr_t& rhs){ if(&rhs!=this){ delete content; content = rhs.content; rhs.content = 0; } return *this; } #endif /* SINGLETON_IMPL_HPP_ */