PageRenderTime 14ms CodeModel.GetById 9ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/pool/detail/singleton.hpp

http://hadesmem.googlecode.com/
C++ Header | 107 lines | 38 code | 16 blank | 53 comment | 0 complexity | c4a1ae93bbd7e8e9eb5abd319cffdd7d MD5 | raw file
  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