/home/andreas/src/svn/mapnik/include/mapnik/utils.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * 
00003  * This file is part of Mapnik (c++ mapping toolkit)
00004  *
00005  * Copyright (C) 2006 Artem Pavlenko
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  *****************************************************************************/
00022 
00023 //$Id: utils.hpp 39 2005-04-10 20:39:53Z pavlenko $
00024 
00025 #ifndef UTILS_HPP
00026 #define UTILS_HPP
00027 // stl
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 // boost
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                                   // register destruction
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

Generated on Thu Jul 19 17:59:27 2007 for Mapnik by  doxygen 1.4.7