00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef cxxtools_Singleton_h
00030 #define cxxtools_Singleton_h
00031
00032 #include <cxxtools/noncopyable.h>
00033
00034 #include <memory>
00035 #include <cstdlib>
00036
00037 namespace cxxtools {
00038
00060 template <typename T, typename A = std::allocator<T> >
00061 class Singleton : private NonCopyable
00062 {
00063 public:
00064 typedef A Allocator;
00065
00066 public:
00075 static T& instance()
00076 {
00077 if(!_instance)
00078 {
00079 try
00080 {
00081 _instance = (T*)_allocator.allocate(1);
00082 new (_instance) T();
00083 std::atexit(&atExit);
00084 }
00085 catch( const std::bad_alloc& e )
00086 {
00087 throw e;
00088 }
00089 catch(...)
00090 {
00091 _allocator.deallocate(_instance, 1);
00092 _instance = 0;
00093 throw;
00094 }
00095 }
00096
00097 return *_instance;
00098 }
00099
00100 protected:
00103 Singleton()
00104 { }
00105
00108 ~Singleton()
00109 { }
00110
00111 private:
00118 static void atExit()
00119 {
00120 _instance->~T();
00121 _allocator.deallocate(_instance, 1);
00122 _instance = 0;
00123 }
00124
00125 private:
00126 static A _allocator;
00127 static T* _instance;
00128 };
00129
00130
00131 template <typename T, typename A>
00132 A Singleton<T, A>::_allocator;
00133
00134
00135 template <typename T, typename A>
00136 T* Singleton<T, A>::_instance = 0;
00137
00138 }
00139
00140 #endif