HyperspaceExplorer 0.7.1
SingletonHolder.h
00001 
00002 // The Loki Library
00003 // Copyright (c) 2001 by Andrei Alexandrescu
00004 // This code accompanies the book:
00005 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
00006 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00007 // Permission to use, copy, modify, distribute and sell this software for any
00008 //     purpose is hereby granted without fee, provided that the above copyright
00009 //     notice appear in all copies and that both that copyright notice and this
00010 //     permission notice appear in supporting documentation.
00011 // The author or Addison-Wesley Longman make no representations about the
00012 //     suitability of this software for any purpose. It is provided "as is"
00013 //     without express or implied warranty.
00015 #ifndef LOKI_SINGLETON_INC_
00016 #define LOKI_SINGLETON_INC_
00017 
00018 // $Id$
00019 
00020 #include <algorithm>
00021 #include <stdexcept>
00022 #include <cassert>
00023 #include <cstdlib>
00024 #include <new>
00025 #include <vector>
00026 #include <list>
00027 #include <memory>
00028 
00041 
00042 
00044 
00060 namespace Loki
00061 {
00062 
00068 
00069     template <class T> struct CreateUsingNew
00070     {
00072         static T* Create()
00073         { return new T; }
00074 
00076         static void Destroy(T* p)
00077         { delete p; }
00078     };
00079 
00086 
00087     template<template<class> class Alloc>
00088     struct CreateUsing
00089     {
00090         template <class T>
00091         struct Allocator
00092         {
00093             static Alloc<T> allocator;  
00094 
00096             static T* Create()
00097             {
00098                 return new (allocator.allocate(1)) T;
00099             }
00100 
00102             static void Destroy(T* p)
00103             {
00104                 //allocator.destroy(p);
00105                 p->~T();
00106                 allocator.deallocate(p,1);
00107             }
00108         };
00109     };
00110 
00117 
00118     template <class T> struct CreateUsingMalloc
00119     {
00121         static T* Create()
00122         {
00123             void* p = std::malloc(sizeof(T));
00124             if (!p) return 0;
00125             return new(p) T;
00126         }
00127 
00129         static void Destroy(T* p)
00130         {
00131             p->~T();
00132             std::free(p);
00133         }
00134     };
00135 
00136 
00145 
00146     template <class T> struct CreateStatic
00147     {
00149         union MaxAlign
00150         {
00151             char t_[sizeof(T)];             
00152             short int shortInt_;            
00153             int int_;                       
00154             long int longInt_;              
00155             float float_;                   
00156             double double_;                 
00157             long double longDouble_;        
00158             struct Test;
00159             int Test::* pMember_;           
00160             int (Test::*pMemberFn_)(int);   
00161         };
00162 
00164         static T* Create()
00165         {
00166             static MaxAlign staticMemory_;
00167             return new(&staticMemory_) T;
00168         }
00169 
00171         static void Destroy(T* p)
00172         {
00173             p->~T();
00174         }
00175     };
00176 
00177 
00190 
00191     template
00192     <
00193         typename T,
00194         template <class> class CreationPolicy = CreateUsingNew
00195     >
00196     class SingletonHolder
00197     {
00198     public:
00199 
00201         typedef T ObjectType;
00202 
00204         static T& Instance();
00205 
00206     private:
00207         // Helpers
00208         static void MakeInstance();         
00209         static void DestroySingleton();     
00210 
00211         // Protection
00212         SingletonHolder();
00213 
00214         // Data
00215         typedef T* PtrInstanceType;         
00216         static PtrInstanceType pInstance_;  
00217         static bool destroyed_;             
00218     };
00219 
00221     // SingletonHolder's data
00223 
00224     template
00225     <
00226         class T,
00227         template <class> class C
00228     >
00229     typename SingletonHolder<T, C>::PtrInstanceType
00230         SingletonHolder<T, C>::pInstance_ = 0;
00231 
00232     template
00233     <
00234         class T,
00235         template <class> class C
00236     >
00237     bool SingletonHolder<T, C>::destroyed_ = false;
00238 
00240     // SingletonHolder::Instance
00242 
00243     template
00244     <
00245         class T,
00246         template <class> class CreationPolicy
00247     >
00248     inline T& SingletonHolder<T, CreationPolicy>::Instance()
00249     {
00250         if (!pInstance_)
00251         {
00252             MakeInstance();
00253         }
00254         return *pInstance_;
00255     }
00256 
00258     // SingletonHolder::MakeInstance (helper for Instance)
00260 
00261     template
00262     <
00263         class T,
00264         template <class> class CreationPolicy
00265     >
00266     void SingletonHolder<T, CreationPolicy>::MakeInstance()
00267     {
00268         if (!pInstance_)
00269         {
00270             if (destroyed_)
00271             {
00272                 destroyed_ = false;
00273             }
00274             pInstance_ = CreationPolicy<T>::Create();
00275         }
00276     }
00277 
00278     template
00279     <
00280         class T,
00281         template <class> class CreationPolicy
00282     >
00283     void
00284     SingletonHolder<T, CreationPolicy>::DestroySingleton()
00285     {
00286         assert(!destroyed_);
00287         CreationPolicy<T>::Destroy(pInstance_);
00288         pInstance_ = 0;
00289         destroyed_ = true;
00290     }
00291 
00292 
00304 
00305 #ifndef LOKI_SINGLETON_EXPORT
00306 #define LOKI_SINGLETON_EXPORT
00307 #endif
00308 
00309     template<class T>
00310     class LOKI_SINGLETON_EXPORT Singleton
00311     {
00312     public:
00313         static T& Instance();   
00314     };
00315 
00316 } // namespace Loki
00317 
00318 
00322 
00323 #define LOKI_SINGLETON_INSTANCE_DEFINITION(SHOLDER)                     \
00324 namespace Loki                                                          \
00325 {                                                                        \
00326     template<>                                                          \
00327     SHOLDER::ObjectType&  Singleton<SHOLDER::ObjectType>::Instance()    \
00328     {                                                                   \
00329         return SHOLDER::Instance();                                     \
00330     }                                                                    \
00331 }
00332 
00333 
00334 #endif // end file guardian
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends

Generated on Mon Apr 9 2012 20:25:16 for HyperspaceExplorer 0.7.1 by doxygen 1.7.4  -  Hosted bySourceForge.net Logo