// Copyright (C) 2000 Stephen Cleary

//

// Distributed under the Boost Software License, Version 1.0. (See

// accompanying file LICENSE_1_0.txt or copy at

// http://www.boost.org/LICENSE_1_0.txt)

//

// See http://www.boost.org for updates, documentation, and revision history.



#ifndef BOOST_POOL_SINGLETON_HPP

#define BOOST_POOL_SINGLETON_HPP



// The following code might be put into some Boost.Config header in a later revision

#ifdef __BORLANDC__

# pragma option push -w-inl

#endif



//

// The following helper classes are placeholders for a generic "singleton"

//  class.  The classes below support usage of singletons, including use in

//  program startup/shutdown code, AS LONG AS there is only one thread

//  running before main() begins, and only one thread running after main()

//  exits.

//

// This class is also limited in that it can only provide singleton usage for

//  classes with default constructors.

//



// The design of this class is somewhat twisted, but can be followed by the

//  calling inheritance.  Let us assume that there is some user code that

//  calls "singleton_default<T>::instance()".  The following (convoluted)

//  sequence ensures that the same function will be called before main():

//    instance() contains a call to create_object.do_nothing()

//    Thus, object_creator is implicitly instantiated, and create_object

//      must exist.

//    Since create_object is a static member, its constructor must be

//      called before main().

//    The constructor contains a call to instance(), thus ensuring that

//      instance() will be called before main().

//    The first time instance() is called (i.e., before main()) is the

//      latest point in program execution where the object of type T

//      can be created.

//    Thus, any call to instance() will auto-magically result in a call to

//      instance() before main(), unless already present.

//  Furthermore, since the instance() function contains the object, instead

//  of the singleton_default class containing a static instance of the

//  object, that object is guaranteed to be constructed (at the latest) in

//  the first call to instance().  This permits calls to instance() from

//  static code, even if that code is called before the file-scope objects

//  in this file have been initialized.



namespace boost {



namespace details {

namespace pool {



// T must be: no-throw default constructible and no-throw destructible

template <typename T>

struct singleton_default

{

  private:

    struct object_creator

    {

      // This constructor does nothing more than ensure that instance()

      //  is called before main() begins, thus creating the static

      //  T object before multithreading race issues can come up.

      object_creator() { singleton_default<T>::instance(); }

      inline void do_nothing() const { }

    };

    static object_creator create_object;



    singleton_default();



  public:

    typedef T object_type;



    // If, at any point (in user code), singleton_default<T>::instance()

    //  is called, then the following function is instantiated.

    static object_type & instance()

    {

      // This is the object that we return a reference to.

      // It is guaranteed to be created before main() begins because of

      //  the next line.

      static object_type obj;



      // The following line does nothing else than force the instantiation

      //  of singleton_default<T>::create_object, whose constructor is

      //  called before main() begins.

      create_object.do_nothing();



      return obj;

    }

};

template <typename T>

typename singleton_default<T>::object_creator

singleton_default<T>::create_object;



} // namespace pool

} // namespace details



} // namespace boost



// The following code might be put into some Boost.Config header in a later revision

#ifdef __BORLANDC__

# pragma option pop

#endif



#endif

