b7b2814ac8fd485149bf3371928532caa4f34d12
[senf.git] / senf / Utils / singleton.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief singleton public header */
25
26 #ifndef HH_SENF_Utils_singleton_
27 #define HH_SENF_Utils_singleton_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31
32 //#include "singleton.mpp"
33 ///////////////////////////////hh.p////////////////////////////////////////
34
35 namespace senf {
36
37     /** \brief Mark a class as singleton and provide singleton accessor
38
39         This mixin class will mark a class as singleton and provide an accessor function to access
40         this singleton instance. The following preconditions must be met for this class to work as
41         advertised:
42         \li There must be only a single thread executing before main() starts. (This should always
43             be the case)
44         \li There must be only a single thread executing after main() ends. (This is always
45             important, otherwise global object destruction might fail)
46         \li The singleton class must have a non throwing default constructor and destructor
47
48         If these conditions are met, this mixin will ensure that the singleton is constructed \e
49         before main even starts executing. If static construction code calls the instance() member,
50         it is ensured, that the instance is constructed no later than the first call to instance().
51
52         Usage example:
53         \code
54           class SomeClass
55               : public senf::singleton<SomeClass>
56           {
57               // Must have default constructor
58               SomeClass();
59
60               // Give singleton access to the constructor
61               friend class senf::singleton<SomeClass>;
62
63         public:
64               // By default 'instance()' is protected. If you want, you may make it public:
65               using senf::singleton<SomeClass>::instance;
66
67               // ...
68           };
69
70           int main(int argc, char ** argv)
71           {
72               // At this point, the instance has already been constructed
73
74               SomeClass::instance().doSomething();
75           }
76         \endcode
77
78         \warning The singleton class should \e not have any static data members since it cannot be
79             guaranteed, that these members will be constructed before the singleton instance.
80
81         \implementation This implementation is directly taken from
82             <tt>boost/pool/detail/singleton.hpp</tt>. See that file for a description of the
83             technique. The only difference is, that I prefer to advertise this class as a mixin
84             (though it may be used the same way as the original too).
85      */
86     template <class Self>
87     class singleton
88         : boost::noncopyable
89     {
90     protected:
91         singleton();
92         ~singleton();
93
94         static Self & instance();       ///< Return singleton instance
95         static bool alive();            ///< Return \c true, if instance ok, \c false otherwise
96
97     private:
98         /** \brief Internal
99             \internal
100          */
101         struct force_creation
102         {
103             force_creation();
104             void nop() const;
105         };
106
107         static force_creation creator_;
108         static bool alive_;
109     };
110
111 }
112
113 ///////////////////////////////hh.e////////////////////////////////////////
114 //#include "singleton.cci"
115 //#include "singleton.ct"
116 #include "singleton.cti"
117 #endif
118
119 \f
120 // Local Variables:
121 // mode: c++
122 // fill-column: 100
123 // c-file-style: "senf"
124 // indent-tabs-mode: nil
125 // ispell-local-dictionary: "american"
126 // compile-command: "scons -u test"
127 // comment-column: 40
128 // End: