switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / singleton.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief singleton public header */
30
31 #ifndef HH_SENF_Utils_singleton_
32 #define HH_SENF_Utils_singleton_ 1
33
34 // Custom includes
35 #include <boost/utility.hpp>
36
37 //#include "singleton.mpp"
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 namespace senf {
41
42     /** \brief Mark a class as singleton and provide singleton accessor
43
44         This mixin class will mark a class as singleton and provide an accessor function to access
45         this singleton instance. The following preconditions must be met for this class to work as
46         advertised:
47         \li There must be only a single thread executing before main() starts. (This should always
48             be the case)
49         \li There must be only a single thread executing after main() ends. (This is always
50             important, otherwise global object destruction might fail)
51         \li The singleton class must have a non throwing default constructor and destructor
52
53         If these conditions are met, this mixin will ensure that the singleton is constructed \e
54         before main even starts executing. If static construction code calls the instance() member,
55         it is ensured, that the instance is constructed no later than the first call to instance().
56
57         Usage example:
58         \code
59           class SomeClass
60               : public senf::singleton<SomeClass>
61           {
62               // Must have default constructor
63               SomeClass();
64
65               // Give singleton access to the constructor
66               friend class senf::singleton<SomeClass>;
67
68         public:
69               // By default 'instance()' is protected. If you want, you may make it public:
70               using senf::singleton<SomeClass>::instance;
71
72               // ...
73           };
74
75           int main(int argc, char ** argv)
76           {
77               // At this point, the instance has already been constructed
78
79               SomeClass::instance().doSomething();
80           }
81         \endcode
82
83         \warning The singleton class should \e not have any static data members since it cannot be
84             guaranteed, that these members will be constructed before the singleton instance.
85
86         \implementation This implementation is directly taken from
87             <tt>boost/pool/detail/singleton.hpp</tt>. See that file for a description of the
88             technique. The only difference is, that I prefer to advertise this class as a mixin
89             (though it may be used the same way as the original too).
90      */
91     template <class Self>
92     class singleton
93         : boost::noncopyable
94     {
95     protected:
96         singleton();
97         ~singleton();
98
99         static Self & instance();       ///< Return singleton instance
100         static bool alive();            ///< Return \c true, if instance ok, \c false otherwise
101
102     private:
103         /** \brief Internal
104             \internal
105          */
106         struct force_creation
107         {
108             force_creation();
109             void nop() const;
110         };
111
112         static force_creation creator_;
113         static bool alive_;
114     };
115
116 }
117
118 //-/////////////////////////////////////////////////////////////////////////////////////////////////
119 //#include "singleton.cci"
120 //#include "singleton.ct"
121 #include "singleton.cti"
122 #endif
123
124 \f
125 // Local Variables:
126 // mode: c++
127 // fill-column: 100
128 // c-file-style: "senf"
129 // indent-tabs-mode: nil
130 // ispell-local-dictionary: "american"
131 // compile-command: "scons -u test"
132 // comment-column: 40
133 // End: