Initial commit.
This commit is contained in:
183
libs/staticsingleton.h
Normal file
183
libs/staticsingleton.h
Normal file
@ -0,0 +1,183 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \file static_singleton.hpp
|
||||
* \date 6.8.2009
|
||||
* \author Potěšil Josef xpotes03
|
||||
* \brief Soubor obsahuje šablonu třídy cStaticSingleton.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef _STATIC_SINGLETON_HPP_
|
||||
#define _STATIC_SINGLETON_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Předdefinovaná třída podporující model větvení do vláken pro
|
||||
* spolupráci s šablonou cStaticSingleton pro použití ve vícevláknových
|
||||
* aplikacích. Využívá zámky z knihovny Boost::Threads.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct MultiThreading
|
||||
{
|
||||
typedef boost::mutex mutex;
|
||||
typedef boost::mutex::scoped_lock scoped_lock;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Předdefinovaná třída pro spolupráci s šablonou cStaticSingleton pro
|
||||
* použití v jednovláknových aplikacích.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class SingleThreading
|
||||
{
|
||||
struct empty {};
|
||||
struct scoped_guard
|
||||
{
|
||||
scoped_guard(empty& ) {}
|
||||
};
|
||||
public:
|
||||
typedef empty mutex;
|
||||
typedef scoped_guard scoped_lock;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Šablonová třída obsahující jednoduchou implementaci návrhového vzoru
|
||||
* Singleton, která umožňuje vytvořit jedináčka z jakékoli třídy, která
|
||||
* má bezparametrový konstruktor.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel = SingleThreading>
|
||||
class cStaticSingleton
|
||||
{
|
||||
public:
|
||||
static Host* Instance();
|
||||
static Host& GetInstance();
|
||||
|
||||
private:
|
||||
cStaticSingleton();
|
||||
cStaticSingleton(const cStaticSingleton& s);
|
||||
cStaticSingleton& operator=(const cStaticSingleton& s);
|
||||
~cStaticSingleton();
|
||||
static Host& Create();
|
||||
static Host& Access();
|
||||
|
||||
typedef Host& (*access_function)();
|
||||
|
||||
static Host* _instance;
|
||||
static bool _destroyed;
|
||||
static access_function _access;
|
||||
static typename ThreadingModel::mutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Funkce pro přístup k jediné instanci třídy.
|
||||
* \return Ukazatele na instanci.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
inline Host* cStaticSingleton<Host, ThreadingModel>::Instance()
|
||||
{
|
||||
return &(GetInstance());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Funkce pro přístup k jediné instanci třídy.
|
||||
* \return Referenci instanci.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
inline Host& cStaticSingleton<Host, ThreadingModel>::GetInstance()
|
||||
{
|
||||
return _access();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Konstruktor.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
cStaticSingleton<Host, ThreadingModel>::cStaticSingleton()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Destruktor.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
cStaticSingleton<Host, ThreadingModel>::~cStaticSingleton()
|
||||
{
|
||||
_instance = 0;
|
||||
_destroyed = true;
|
||||
_access = &cStaticSingleton<Host, ThreadingModel>::Create;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Interní funkce třídy vytvářející samotnou instanci objektu.
|
||||
* Pro korektní práci ve vícevláknovém prostředí je potřeba
|
||||
* odkomentovat/upravit testující a uzamykací část
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
Host& cStaticSingleton<Host, ThreadingModel>::Create()
|
||||
{
|
||||
typename ThreadingModel::scoped_lock scoped_lock(_mutex);
|
||||
if (!_instance)
|
||||
{
|
||||
if (!_destroyed)
|
||||
{ // Vytvoř jedinou instanci a změň ukazatele _access, kterým byla
|
||||
// tato metoda zavolána, aby se již nezavolala a místo toho
|
||||
// se volala funkce zpřístupňující samotnou instanci
|
||||
static Host staticInstance;
|
||||
_instance = &staticInstance;
|
||||
_access = &cStaticSingleton<Host, ThreadingModel>::Access;
|
||||
}
|
||||
else
|
||||
{ // Došlo k přístupu k již zničenému jedináčkovi
|
||||
throw std::runtime_error("Access to dead reference of an object.");
|
||||
}
|
||||
}
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* \brief Funkce zpřístupňující instanci hostující třídy.
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class ThreadingModel>
|
||||
Host& cStaticSingleton<Host, ThreadingModel>::Access()
|
||||
{
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Jedináčkova data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Host, class TM>
|
||||
Host* cStaticSingleton<Host, TM>::_instance = 0;
|
||||
|
||||
template<class H, class TM>
|
||||
bool cStaticSingleton<H, TM>::_destroyed = false;
|
||||
|
||||
template<class H, class TM> typename cStaticSingleton<H, TM>::access_function
|
||||
cStaticSingleton<H, TM>::_access = &cStaticSingleton<H, TM>::Create;
|
||||
|
||||
template<class H, class ThreadingModel> typename ThreadingModel::mutex
|
||||
cStaticSingleton<H, ThreadingModel>::_mutex;
|
||||
|
||||
#endif // _STATIC_SINGLETON_HPP_
|
Reference in New Issue
Block a user