00001 /* 00002 libwt - Vassilis Virvilis Toolkit - a widget library 00003 Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, SA. 00019 */ 00020 00021 #ifndef WT_SINGLETON_H 00022 #define WT_SINGLETON_H 00023 00024 #include <cassert> 00025 #include <exception> 00026 00027 namespace Wt { 00028 00029 template <class DERIVED> 00030 class Singleton { 00031 public: 00032 static DERIVED *instance() { 00033 return (instance_) ? instance_ : DERIVED::load(); 00034 } 00035 00036 static DERIVED *existingInstance() { 00037 return instance_; 00038 } 00039 00040 ///instantiates the pointer compatible child of DERIVED aka grandchild 00041 /*! it is handy in driver like situations */ 00042 template <class GRANDCHILD> 00043 static DERIVED* instance() { 00044 return (instance_) ? instance_ : GRANDCHILD::load(); 00045 } 00046 00047 /// initializes the object 00048 ///\note cannot fail 00049 static void init() { 00050 if (!instance()) { 00051 assert(0); 00052 } 00053 } 00054 00055 static void quit() { 00056 delete instance(); 00057 } 00058 00059 class Exception : public std::exception { 00060 virtual const char *what() const throw() { 00061 return "Attempt to create second Singleton object"; 00062 } 00063 }; 00064 00065 protected: 00066 /// Derived class public constructor 00067 /*! if the constructor of the derived class is public 00068 we have to call this constructor to properly set the 00069 instance 00070 */ 00071 Singleton(DERIVED *d) { 00072 if (instance_) { 00073 throw Exception(); 00074 } 00075 instance_ = d; 00076 } 00077 00078 ~Singleton() { 00079 instance_ = 0; 00080 } 00081 /// try to load the instance 00082 /*! if it fails return NULL 00083 if it succeeds must return 00084 the newly created object 00085 */ 00086 static DERIVED *load() { 00087 instance_ = new DERIVED; 00088 return instance_; 00089 } 00090 00091 static DERIVED* instance_; 00092 }; 00093 00094 template<typename DERIVED> 00095 DERIVED * Singleton<DERIVED>::instance_ = 0; 00096 00097 } //namespace 00098 00099 #endif //WT_SINGLETON_H
This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.