00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * * 00009 * License * 00010 * * 00011 * This library is free software; you can redistribute it and/or modify it * 00012 * under the terms of the GNU Library General Public License as published * 00013 * by the Free Software Foundation, version 2. * 00014 * * 00015 * This library is distributed in the hope that it will be useful, but * 00016 * WITHOUT ANY WARRANTY; without even the implied warranty of * 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00018 * Library General Public License for more details. * 00019 * * 00020 * You should have received a copy of the GNU Library General Public * 00021 * License along with this library; if not, write to the Free Software * 00022 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00023 * * 00024 \*===========================================================================*/ 00025 00026 00027 //============================================================================= 00028 // 00029 // Implements a simple singleton template 00030 // 00031 //============================================================================= 00032 00033 00034 #ifndef __SINGLETON_HH__ 00035 #define __SINGLETON_HH__ 00036 00037 00038 //=== INCLUDES ================================================================ 00039 00040 // OpenMesh 00041 #include <OpenMesh/Core/System/config.hh> 00042 00043 // STL 00044 #include <stdexcept> 00045 #include <iostream> 00046 00047 00048 //== NAMESPACES =============================================================== 00049 00050 00051 namespace OpenMesh { 00052 00053 00054 //=== IMPLEMENTATION ========================================================== 00055 00056 00061 template <typename T> 00062 class SingletonT 00063 { 00064 public: 00065 00072 static T& Instance() 00073 { 00074 if (!pInstance__) 00075 { 00076 // check if singleton alive 00077 if (destroyed__) 00078 { 00079 OnDeadReference(); 00080 } 00081 // first time request -> initialize 00082 else 00083 { 00084 Create(); 00085 } 00086 } 00087 return *pInstance__; 00088 } 00089 00090 00091 private: 00092 00093 // Disable constructors/assignment to enforce uniqueness 00094 SingletonT(); 00095 SingletonT(const SingletonT&); 00096 SingletonT& operator=(const SingletonT&); 00097 00098 // Create a new singleton and store its pointer 00099 static void Create() 00100 { 00101 static T theInstance; 00102 pInstance__ = &theInstance; 00103 } 00104 00105 // Will be called if instance is accessed after its lifetime has expired 00106 static void OnDeadReference() 00107 { 00108 throw std::runtime_error("[Singelton error] - Dead reference detected!\n"); 00109 } 00110 00111 virtual ~SingletonT() 00112 { 00113 pInstance__ = 0; 00114 destroyed__ = true; 00115 } 00116 00117 static T* pInstance__; 00118 static bool destroyed__; 00119 }; 00120 00121 00122 00123 //============================================================================= 00124 } // namespace OpenMesh 00125 //============================================================================= 00126 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SINGLETON_C) 00127 # define OPENMESH_SINGLETON_TEMPLATES 00128 # include "SingletonT.cc" 00129 #endif 00130 //============================================================================= 00131 #endif // __SINGLETON_HH__ 00132 //=============================================================================