summaryrefslogtreecommitdiff
path: root/include/util/Singleton.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/util/Singleton.hpp')
-rwxr-xr-xinclude/util/Singleton.hpp65
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
+