1 | // Copyright (C) 2000 Stephen Cleary |
---|
2 | // |
---|
3 | // Distributed under the Boost Software License, Version 1.0. (See |
---|
4 | // accompanying file LICENSE_1_0.txt or copy at |
---|
5 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
6 | // |
---|
7 | // See http://www.boost.org for updates, documentation, and revision history. |
---|
8 | |
---|
9 | #ifndef BOOST_POOL_SINGLETON_HPP |
---|
10 | #define BOOST_POOL_SINGLETON_HPP |
---|
11 | |
---|
12 | // The following code might be put into some Boost.Config header in a later revision |
---|
13 | #ifdef __BORLANDC__ |
---|
14 | # pragma option push -w-inl |
---|
15 | #endif |
---|
16 | |
---|
17 | // |
---|
18 | // The following helper classes are placeholders for a generic "singleton" |
---|
19 | // class. The classes below support usage of singletons, including use in |
---|
20 | // program startup/shutdown code, AS LONG AS there is only one thread |
---|
21 | // running before main() begins, and only one thread running after main() |
---|
22 | // exits. |
---|
23 | // |
---|
24 | // This class is also limited in that it can only provide singleton usage for |
---|
25 | // classes with default constructors. |
---|
26 | // |
---|
27 | |
---|
28 | // The design of this class is somewhat twisted, but can be followed by the |
---|
29 | // calling inheritance. Let us assume that there is some user code that |
---|
30 | // calls "singleton_default<T>::instance()". The following (convoluted) |
---|
31 | // sequence ensures that the same function will be called before main(): |
---|
32 | // instance() contains a call to create_object.do_nothing() |
---|
33 | // Thus, object_creator is implicitly instantiated, and create_object |
---|
34 | // must exist. |
---|
35 | // Since create_object is a static member, its constructor must be |
---|
36 | // called before main(). |
---|
37 | // The constructor contains a call to instance(), thus ensuring that |
---|
38 | // instance() will be called before main(). |
---|
39 | // The first time instance() is called (i.e., before main()) is the |
---|
40 | // latest point in program execution where the object of type T |
---|
41 | // can be created. |
---|
42 | // Thus, any call to instance() will auto-magically result in a call to |
---|
43 | // instance() before main(), unless already present. |
---|
44 | // Furthermore, since the instance() function contains the object, instead |
---|
45 | // of the singleton_default class containing a static instance of the |
---|
46 | // object, that object is guaranteed to be constructed (at the latest) in |
---|
47 | // the first call to instance(). This permits calls to instance() from |
---|
48 | // static code, even if that code is called before the file-scope objects |
---|
49 | // in this file have been initialized. |
---|
50 | |
---|
51 | namespace boost { |
---|
52 | |
---|
53 | namespace details { |
---|
54 | namespace pool { |
---|
55 | |
---|
56 | // T must be: no-throw default constructible and no-throw destructible |
---|
57 | template <typename T> |
---|
58 | struct singleton_default |
---|
59 | { |
---|
60 | private: |
---|
61 | struct object_creator |
---|
62 | { |
---|
63 | // This constructor does nothing more than ensure that instance() |
---|
64 | // is called before main() begins, thus creating the static |
---|
65 | // T object before multithreading race issues can come up. |
---|
66 | object_creator() { singleton_default<T>::instance(); } |
---|
67 | inline void do_nothing() const { } |
---|
68 | }; |
---|
69 | static object_creator create_object; |
---|
70 | |
---|
71 | singleton_default(); |
---|
72 | |
---|
73 | public: |
---|
74 | typedef T object_type; |
---|
75 | |
---|
76 | // If, at any point (in user code), singleton_default<T>::instance() |
---|
77 | // is called, then the following function is instantiated. |
---|
78 | static object_type & instance() |
---|
79 | { |
---|
80 | // This is the object that we return a reference to. |
---|
81 | // It is guaranteed to be created before main() begins because of |
---|
82 | // the next line. |
---|
83 | static object_type obj; |
---|
84 | |
---|
85 | // The following line does nothing else than force the instantiation |
---|
86 | // of singleton_default<T>::create_object, whose constructor is |
---|
87 | // called before main() begins. |
---|
88 | create_object.do_nothing(); |
---|
89 | |
---|
90 | return obj; |
---|
91 | } |
---|
92 | }; |
---|
93 | template <typename T> |
---|
94 | typename singleton_default<T>::object_creator |
---|
95 | singleton_default<T>::create_object; |
---|
96 | |
---|
97 | } // namespace pool |
---|
98 | } // namespace details |
---|
99 | |
---|
100 | } // namespace boost |
---|
101 | |
---|
102 | // The following code might be put into some Boost.Config header in a later revision |
---|
103 | #ifdef __BORLANDC__ |
---|
104 | # pragma option pop |
---|
105 | #endif |
---|
106 | |
---|
107 | #endif |
---|