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 #ifndef UTILS_HPP
00026 #define UTILS_HPP
00027
00028 #include <stdexcept>
00029 #include <cstdlib>
00030 #include <limits>
00031 #include <ctime>
00032 #include <sstream>
00033 #include <iostream>
00034 #include <algorithm>
00035 #include <cmath>
00036
00037 #include <boost/thread/mutex.hpp>
00038
00039 namespace mapnik
00040 {
00041 using boost::mutex;
00042
00043 template <typename T>
00044 class CreateUsingNew
00045 {
00046 public:
00047 static T* create()
00048 {
00049 return new T;
00050 }
00051 static void destroy(T* obj)
00052 {
00053 delete obj;
00054 }
00055 };
00056
00057 template <typename T>
00058 class CreateStatic
00059 {
00060 private:
00061 union MaxAlign
00062 {
00063 char t_[sizeof(T)];
00064 short int shortInt_;
00065 int int_;
00066 long int longInt_;
00067 float float_;
00068 double double_;
00069 long double longDouble_;
00070 struct Test;
00071 int Test::* pMember_;
00072 int (Test::*pMemberFn_)(int);
00073 };
00074
00075 public:
00076
00077 static T* create()
00078 {
00079 static MaxAlign staticMemory;
00080 return new(&staticMemory) T;
00081 }
00082
00083 static void destroy(volatile T* obj)
00084 {
00085 obj->~T();
00086 }
00087 };
00088
00089 template <typename T,
00090 template <typename T> class CreatePolicy=CreateStatic> class singleton
00091 {
00092 friend class CreatePolicy<T>;
00093 static T* pInstance_;
00094 static bool destroyed_;
00095 singleton(const singleton &rhs);
00096 singleton& operator=(const singleton&);
00097 static void onDeadReference()
00098 {
00099 throw std::runtime_error("dead reference!");
00100 }
00101
00102 static void DestroySingleton()
00103 {
00104 CreatePolicy<T>::destroy(pInstance_);
00105 pInstance_ = 0;
00106 destroyed_=true;
00107 #ifdef MAPNIK_DEBUG
00108 std::clog << " destroyed singleton \n";
00109 #endif
00110 }
00111
00112 protected:
00113 static mutex mutex_;
00114 singleton() {}
00115 public:
00116 static T* instance()
00117 {
00118 if (!pInstance_)
00119 {
00120 mutex::scoped_lock lock(mutex_);
00121 if (!pInstance_)
00122 {
00123 if (destroyed_)
00124 {
00125 onDeadReference();
00126 }
00127 else
00128 {
00129 pInstance_=CreatePolicy<T>::create();
00130
00131 std::atexit(&DestroySingleton);
00132 }
00133 }
00134 }
00135 return pInstance_;
00136 }
00137 };
00138
00139 template <typename T,
00140 template <typename T> class CreatePolicy> mutex singleton<T,CreatePolicy>::mutex_;
00141 template <typename T,
00142 template <typename T> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
00143 template <typename T,
00144 template <typename T> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
00145
00146 }
00147
00148
00149 #endif //UTILS_HPP