diff options
Diffstat (limited to 'include/util/Singleton.hpp')
-rwxr-xr-x | include/util/Singleton.hpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/include/util/Singleton.hpp b/include/util/Singleton.hpp new file mode 100755 index 0000000..1bfb460 --- /dev/null +++ b/include/util/Singleton.hpp @@ -0,0 +1,65 @@ +#ifndef __SINGLETON_H +#define __SINGLETON_H + +#include "ScopedPtr.hpp" +#include "NonCopyable.hpp" +#include "Exportable.hpp" +#include "Noreturn.hpp" + +#include <cstdlib> +#include <stdexcept> + +#define DECLARE_SINGLETON( T ) \ + friend class scopedPtr< T >; \ + friend class Singleton< T >; + +#define DEFINE_SINGLETON( T ) \ + SINGLETON_EXTERN template class SINGLETON_EXPORT Singleton< T >; + +template< class T > +class Singleton : private noncopyable +{ + public: + static T& instance( ) + { + if( destroyed ) { + onDeadReference( ); + } + + if( t == 0 ) { + create( ); + } + + return *t; + } + + protected: + Singleton( ) + { + } + + virtual ~Singleton( ) + { + destroyed = true; + } + + private: + static void create( ) + { + t.reset( new T ); + } + + static void onDeadReference( ) CRAWLER_NORETURN + { + throw std::runtime_error( "singleton has already been destroyed!" ); + } + + static scopedPtr<T> t; + static bool destroyed; +}; + +template< class T > scopedPtr<T> Singleton<T>::t( 0 ); +template< class T > bool Singleton<T>::destroyed( false ); + +#endif + |