// file: singleton.h
#ifndef _LOKI_SINGLETON_H
#define _LOKI_SINGLETON_H 1
#include <mutex>
#include <stdexcept>
#include <cassert>
#include <cstdlib>
#ifdef _MSC_VER
#define LOKI_CDECL __cdecl // C调用约定
#else
#define LOKI_CDECL
#endif
namespace loki {
/单件模版/
template<typename T>
class singleton_holder {
public:
typedef T ObjType;
static T& instance();
private:
singleton_holder();
static void makeInstance();
static void LOKI_CDECL destroySingleton();
typedef T* InstancePtr;
static InstancePtr _spInstance;
static std::once_flag _sOnceFlag;
};
//
template<typename T>
typename singleton_holder<T>::InstancePtr singleton_holder<T>::_spInstance = nullptr;
template<typename T>
std::once_flag singleton_holder<T>::_sOnceFlag;
template<typename T>
inline T& singleton_holder<T>::instance() {
std::call_once(_sOnceFlag, &makeInstance);
return *_spInstance;
}
template<typename T>
void singleton_holder<T>::makeInstance() {
_spInstance = new T();
std::atexit(&destroySingleton);
}
template<typename T>
void LOKI_CDECL singleton_holder<T>::destroySingleton() {
delete _spInstance;
_spInstance = nullptr;
}
} //namespace loki
#define NULL_EXPORT
// no namwspace
#define LOKI_SINGLETON_DEF_H(SINGLETON_EXPORT) \
template<class T> \
class SINGLETON_EXPORT singleton { \
public: \
static T& instance(); \
};
#define LOKI_SINGLETON_DEF_CPP(SINGLETON_HOLDER) \
template<> \
SINGLETON_HOLDER::ObjType& singleton<SINGLETON_HOLDER::ObjType>::instance() { \
return SINGLETON_HOLDER::instance(); \
}
// use namespace
#define LOKI_NAMESPACE_SINGLETON_DEF_H(NS, SINGLETON_EXPORT) \
namespace NS { \
template<class T> \
class SINGLETON_EXPORT singleton { \
public: \
static T& instance(); \
}; \
}
#define LOKI_NAMESPACE_SINGLETON_DEF_CPP(NS, SINGLETON_HOLDER) \
namespace NS { \
template<> \
SINGLETON_HOLDER::ObjType& singleton<SINGLETON_HOLDER::ObjType>::instance() { \
return SINGLETON_HOLDER::instance(); \
} \
}
#endif //_LOKI_SINGLETON_H