Files
core_misc/tjp/core/singleton/ThreadSpecificSingleton.hpp
Timothy Prepscius fa54be052a flatten 20260225
2026-02-25 12:39:24 -05:00

133 lines
2.4 KiB
C++
Executable File

// TJP COPYRIGHT HEADER
/**
* legal header
*
* ============================================================================
* TJP 10/11/01 Got rid of the constructed singleton, it was essentially
* a pointer!
*
* @author Timothy Prepscius
* @created 3/../01
*/
#pragma once
#include "ThreadSpecificSingleton.h"
#include "../system/DisableWarningsPush.h"
#include <boost/thread.hpp>
#include "../system/DisableWarningsPop.h"
namespace timprepscius {
namespace core {
/**
* a Singleton container, whose contained instance is constructed on its
* first request
*
* T defines the class pointer type
* X defines the allocation class type
*/
template<class T, class X>
class ThreadSpecificSingletonNoConstruct
{
private:
boost::thread_specific_ptr<T> instance;
static void cleanup_function (T *p) { }
public:
ThreadSpecificSingletonNoConstruct () :
instance(&cleanup_function) { }
virtual ~ThreadSpecificSingletonNoConstruct () {}
virtual void setInstance (T *instance)
{
this->instance.release();
this->instance.reset(instance);
}
void deleteInstance()
{
delete this->instance.release();
}
virtual T *p()
{
return instance.get();
}
/**********************************************************************
* operator overloads to simplify use
**********************************************************************/
operator T *()
{
return p();
}
T *operator ->()
{
return p();
}
T &operator *()
{
return *p();
}
} ;
/**
* a Singleton container, whose contained instance is constructed on its
* first request
*
* T defines the class pointer type
* X defines the allocation class type
*/
template<class T, class X>
class ThreadSpecificSingleton : public ThreadSpecificSingletonNoConstruct<T>
{
protected:
typedef ThreadSpecificSingletonNoConstruct<T> Super;
public:
virtual void setInstance (T *instance)
{
Super::deleteInstance();
Super::setInstance(instance);
}
T *p()
{
T *p = Super::p();
if (!p)
Super::setInstance(p = new X());
return p;
}
/**********************************************************************
* operator overloads to simplify use
**********************************************************************/
operator T *()
{
return p();
}
T *operator ->()
{
return p();
}
T &operator *()
{
return *p();
}
} ;
} // namespace utilities
} // namespace