source: NonGTP/Boost/boost/pool/detail/singleton.hpp @ 857

Revision 857, 3.9 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]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
51namespace boost {
52
53namespace details {
54namespace pool {
55
56// T must be: no-throw default constructible and no-throw destructible
57template <typename T>
58struct 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};
93template <typename T>
94typename singleton_default<T>::object_creator
95singleton_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
Note: See TracBrowser for help on using the repository browser.