]> git.mxchange.org Git - simgear.git/blob - simgear/structure/singleton.hpp
Working 'noshadow' animation
[simgear.git] / simgear / structure / singleton.hpp
1 // Copyright (C) 2000 Stephen Cleary
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // Boost Software License - Version 1.0 - August 17th, 2003
5
6 // Permission is hereby granted, free of charge, to any person or organization
7 // obtaining a copy of the software and accompanying documentation covered by
8 // this license (the "Software") to use, reproduce, display, distribute,
9 // execute, and transmit the Software, and to prepare derivative works of the
10 // Software, and to permit third-parties to whom the Software is furnished to
11 // do so, all subject to the following:
12
13 // The copyright notices in the Software and this entire statement, including
14 // the above license grant, this restriction and the following disclaimer,
15 // must be included in all copies of the Software, in whole or in part, and
16 // all derivative works of the Software, unless such copies or derivative
17 // works are solely in the form of machine-executable object code generated by
18 // a source language processor.
19
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
23 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
24 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
25 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 //
28 // See http://www.boost.org for updates, documentation, and revision history.
29
30 #ifndef BOOST_POOL_SINGLETON_HPP
31 #define BOOST_POOL_SINGLETON_HPP
32
33 // The following code might be put into some Boost.Config header in a later revision
34 #ifdef __BORLANDC__
35 # pragma option push -w-inl
36 #endif
37
38 //
39 // The following helper classes are placeholders for a generic "singleton"
40 //  class.  The classes below support usage of singletons, including use in
41 //  program startup/shutdown code, AS LONG AS there is only one thread
42 //  running before main() begins, and only one thread running after main()
43 //  exits.
44 //
45 // This class is also limited in that it can only provide singleton usage for
46 //  classes with default constructors.
47 //
48
49 // The design of this class is somewhat twisted, but can be followed by the
50 //  calling inheritance.  Let us assume that there is some user code that
51 //  calls "singleton_default<T>::instance()".  The following (convoluted)
52 //  sequence ensures that the same function will be called before main():
53 //    instance() contains a call to create_object.do_nothing()
54 //    Thus, object_creator is implicitly instantiated, and create_object
55 //      must exist.
56 //    Since create_object is a static member, its constructor must be
57 //      called before main().
58 //    The constructor contains a call to instance(), thus ensuring that
59 //      instance() will be called before main().
60 //    The first time instance() is called (i.e., before main()) is the
61 //      latest point in program execution where the object of type T
62 //      can be created.
63 //    Thus, any call to instance() will auto-magically result in a call to
64 //      instance() before main(), unless already present.
65 //  Furthermore, since the instance() function contains the object, instead
66 //  of the singleton_default class containing a static instance of the
67 //  object, that object is guaranteed to be constructed (at the latest) in
68 //  the first call to instance().  This permits calls to instance() from
69 //  static code, even if that code is called before the file-scope objects
70 //  in this file have been initialized.
71
72 namespace boost {
73
74 namespace details {
75 namespace pool {
76
77 // T must be: no-throw default constructible and no-throw destructible
78 template <typename T>
79 struct singleton_default
80 {
81   private:
82     struct object_creator
83     {
84       // This constructor does nothing more than ensure that instance()
85       //  is called before main() begins, thus creating the static
86       //  T object before multithreading race issues can come up.
87       object_creator() { singleton_default<T>::instance(); }
88       inline void do_nothing() const { }
89     };
90     static object_creator create_object;
91
92     singleton_default();
93
94   public:
95     typedef T object_type;
96
97     // If, at any point (in user code), singleton_default<T>::instance()
98     //  is called, then the following function is instantiated.
99     static object_type & instance()
100     {
101       // This is the object that we return a reference to.
102       // It is guaranteed to be created before main() begins because of
103       //  the next line.
104       static object_type obj;
105
106       // The following line does nothing else than force the instantiation
107       //  of singleton_default<T>::create_object, whose constructor is
108       //  called before main() begins.
109       create_object.do_nothing();
110
111       return obj;
112     }
113 };
114 template <typename T>
115 typename singleton_default<T>::object_creator
116 singleton_default<T>::create_object;
117
118 } // namespace pool
119 } // namespace details
120
121 } // namespace boost
122
123 // The following code might be put into some Boost.Config header in a later revision
124 #ifdef __BORLANDC__
125 # pragma option pop
126 #endif
127
128 #endif