library of assembled shared sources |
http://lass.cocamware.com |
00001 /** @file 00002 * @author Bram de Greve (bramz@users.sourceforge.net) 00003 * @author Tom De Muer (tomdemuer@users.sourceforge.net) 00004 * 00005 * *** BEGIN LICENSE INFORMATION *** 00006 * 00007 * The contents of this file are subject to the Common Public Attribution License 00008 * Version 1.0 (the "License"); you may not use this file except in compliance with 00009 * the License. You may obtain a copy of the License at 00010 * http://lass.sourceforge.net/cpal-license. The License is based on the 00011 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 00012 * use of software over a computer network and provide for limited attribution for 00013 * the Original Developer. In addition, Exhibit A has been modified to be consistent 00014 * with Exhibit B. 00015 * 00016 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 00017 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific 00018 * language governing rights and limitations under the License. 00019 * 00020 * The Original Code is LASS - Library of Assembled Shared Sources. 00021 * 00022 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer. 00023 * The Original Developer is the Initial Developer. 00024 * 00025 * All portions of the code written by the Initial Developer are: 00026 * Copyright (C) 2004-2007 the Initial Developer. 00027 * All Rights Reserved. 00028 * 00029 * Contributor(s): 00030 * 00031 * Alternatively, the contents of this file may be used under the terms of the 00032 * GNU General Public License Version 2 or later (the GPL), in which case the 00033 * provisions of GPL are applicable instead of those above. If you wish to allow use 00034 * of your version of this file only under the terms of the GPL and not to allow 00035 * others to use your version of this file under the CPAL, indicate your decision by 00036 * deleting the provisions above and replace them with the notice and other 00037 * provisions required by the GPL License. If you do not delete the provisions above, 00038 * a recipient may use your version of this file under either the CPAL or the GPL. 00039 * 00040 * *** END LICENSE INFORMATION *** 00041 */ 00042 00043 /** @class lass::util::Singleton 00044 * @brief non-intrusive singleton holder. 00045 * @author Bram de Greve 00046 * @date 2003 00047 * 00048 * With this class, it's possible to create a singleton of a class Foo. It's a non-instrusive 00049 * singleton because it's not required to derive Foo from this Singleton class. Instead, 00050 * this class will be a holder to a singleton object of Foo. To use class Foo as a singleton 00051 * is very straight forward, but can be done in a couple of ways: 00052 * 00053 * 1. The @e typedef way: With a typedef, you create a new type that will act as singleton holder 00054 * for class @c Foo. To access the singleton, you must now use the @c instance() method on 00055 * that new type: 00056 * 00057 * @code 00058 * typedef lass::util::Singleton<Foo> TFooSingleton; 00059 * 00060 * TFooSingleton()::instance()->bar(fun); 00061 * @endcode 00062 * 00063 * 2. The @e function way (@b prefered/b>): you write a nice little function that returns a pointer 00064 * to the singleton. To access the singleton, you simple call that function: 00065 * 00066 * @code 00067 * Foo* foo() 00068 * { 00069 * return lass::util::Singleton<Foo>::instance(); 00070 * } 00071 * 00072 * foo()->bar(fun); 00073 * @endcode 00074 * 00075 * Both ways only differ in how to access the instance. All other properties are common: 00076 * 00077 * - The instance of the singleton is constructed on the heap on first access on the heap. i.e. 00078 * the first time in the program @c TFooSingleton::instance() or @c foo() is called, a new object 00079 * of @c Foo is allocated on the heap, and a pointer to it is returned. All the following calls 00080 * will return that same pointer. This is the way how to control the order of construction: 00081 * on first access. 00082 * 00083 * - The order of destruction can be set by the @c DestructionPriority. Singletons with a 00084 * smaller destruction priority will be destructed later than those with a higher destruction 00085 * priority. It's not specified in which order singletons with identical destruction priorities 00086 * will be destructed (i.e. its not guaranteed for such singletons that the last one constructed 00087 * will be the first to be destroyed). You can set the destruction priority by the second 00088 * template argument of @c Singleton: @c lass::util::Singleton<Foo,2000> will specify the 00089 * singleton to have a destruction priority of 2000. The default destruction priority is set to 00090 * be 1000. Priorities below 500 are reserved for the Lass implementation (and for you who 00091 * know what you're doing ;) 00092 * 00093 * @b warning: lass::io::proxyMan() is a proxy man that is needed for the implementation of 00094 * all logging activities etc. Its destruction priority is set to 0 and there should be 00095 * no other singleton have a destruction priority lower or equal than this. 00096 * 00097 * - Requirements for the class @c Foo: Since it has to be constructed on the heap without any 00098 * parameters in the neighbourhoud, it has to have a default constructor. 00099 * 00100 * @b Reference: 00101 * -# ALEXANDRESCU A. (2001), <i>Modern C++ Design: Generic Programming and Design Patterns 00102 * applied</i>, C++ in depth series, Addison-Wesley, pages 129-156 00103 * -# GAMMA E., HELM R., JOHNSON R. & VLISSIDES J. (1995), <i>Design Patters: Elements of 00104 * Reusable Object-Oriented Software</i>, Addison-Wesley. 00105 */ 00106 00107 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_SINGLETON_H 00108 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_SINGLETON_H 00109 00110 #include "util_common.h" 00111 #include "scoped_ptr.h" 00112 #include "impl/singleton_impl.h" 00113 00114 namespace lass 00115 { 00116 namespace util 00117 { 00118 00119 /** Destruction priority constants. 00120 * @relates Singleton 00121 * Priorities levels below singletonDestructionPriorityBeginUserRange (=500) are reserved for the 00122 * implementation of Lass, and should not be used by user code (unless you know what you're doing 00123 * of course ;) 00124 */ 00125 enum DestructionPriorities 00126 { 00127 destructionPriorityDefault = 1000, /**< default priority level =) */ 00128 destructionPriorityBeginUser = 500, /**< lowest legal level for user code */ 00129 00130 // the following levels are internal and should not be used by user code 00131 // 00132 destructionPriorityInternalProxyMan = 0, /**< @internal */ 00133 destructionPriorityInternalPythonMutex = 50, /**< @internal */ 00134 destructionPriorityInternalTlsDestructors = 100, /**< @internal */ 00135 destructionPriorityInternalAllocators = 200, /**< @internal */ 00136 destructionPriorityInternalTlsLocalsMain = 400, /**< @internal */ 00137 }; 00138 00139 template<class T, int destructPriority = destructionPriorityDefault> 00140 class Singleton: public impl::SingletonBase 00141 { 00142 public: 00143 00144 typedef Singleton<T, destructPriority> TSelf; 00145 00146 typedef T TInstance; 00147 enum { destructionPriority = destructPriority }; 00148 00149 Singleton(); 00150 virtual ~Singleton(); 00151 00152 static TInstance* instance(); 00153 00154 private: 00155 00156 static bool deadReference(bool iSetReferenceToDead = false); 00157 00158 ScopedPtr<TInstance> instance_; 00159 }; 00160 00161 } 00162 } 00163 00164 #include "singleton.inl" 00165 00166 #endif 00167 00168 // EOF 00169
Generated on Mon Nov 10 14:21:34 2008 for Library of Assembled Shared Sources by 1.5.7.1 |