library of assembled shared sources

http://lass.cocamware.com

singleton.h

Go to the documentation of this file.
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 doxygen 1.5.7.1
SourceForge.net Logo