Chris@102: // Copyright (C) 2000 Stephen Cleary Chris@102: // Copyright (C) 2008 Ion Gaztanaga Chris@102: // Chris@102: // Distributed under the Boost Software License, Version 1.0. (See Chris@102: // accompanying file LICENSE_1_0.txt or copy at Chris@102: // http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // See http://www.boost.org for updates, documentation, and revision history. Chris@102: // Chris@102: // This file is a modified file from Boost.Pool Chris@102: Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: // Chris@102: // (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // See http://www.boost.org/libs/container for documentation. Chris@102: // Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: Chris@102: #ifndef BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP Chris@102: #define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP Chris@102: Chris@102: #ifndef BOOST_CONFIG_HPP Chris@102: # include Chris@102: #endif Chris@102: Chris@102: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@102: # pragma once Chris@102: #endif Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: // Chris@102: // The following helper classes are placeholders for a generic "singleton" Chris@102: // class. The classes below support usage of singletons, including use in Chris@102: // program startup/shutdown code, AS LONG AS there is only one thread Chris@102: // running before main() begins, and only one thread running after main() Chris@102: // exits. Chris@102: // Chris@102: // This class is also limited in that it can only provide singleton usage for Chris@102: // classes with default constructors. Chris@102: // Chris@102: Chris@102: // The design of this class is somewhat twisted, but can be followed by the Chris@102: // calling inheritance. Let us assume that there is some user code that Chris@102: // calls "singleton_default::instance()". The following (convoluted) Chris@102: // sequence ensures that the same function will be called before main(): Chris@102: // instance() contains a call to create_object.do_nothing() Chris@102: // Thus, object_creator is implicitly instantiated, and create_object Chris@102: // must exist. Chris@102: // Since create_object is a static member, its constructor must be Chris@102: // called before main(). Chris@102: // The constructor contains a call to instance(), thus ensuring that Chris@102: // instance() will be called before main(). Chris@102: // The first time instance() is called (i.e., before main()) is the Chris@102: // latest point in program execution where the object of type T Chris@102: // can be created. Chris@102: // Thus, any call to instance() will auto-magically result in a call to Chris@102: // instance() before main(), unless already present. Chris@102: // Furthermore, since the instance() function contains the object, instead Chris@102: // of the singleton_default class containing a static instance of the Chris@102: // object, that object is guaranteed to be constructed (at the latest) in Chris@102: // the first call to instance(). This permits calls to instance() from Chris@102: // static code, even if that code is called before the file-scope objects Chris@102: // in this file have been initialized. Chris@102: Chris@102: namespace boost { Chris@102: namespace container { Chris@102: namespace container_detail { Chris@102: Chris@102: // T must be: no-throw default constructible and no-throw destructible Chris@102: template Chris@102: struct singleton_default Chris@102: { Chris@102: private: Chris@102: struct object_creator Chris@102: { Chris@102: // This constructor does nothing more than ensure that instance() Chris@102: // is called before main() begins, thus creating the static Chris@102: // T object before multithreading race issues can come up. Chris@102: object_creator() { singleton_default::instance(); } Chris@102: inline void do_nothing() const { } Chris@102: }; Chris@102: static object_creator create_object; Chris@102: Chris@102: singleton_default(); Chris@102: Chris@102: public: Chris@102: typedef T object_type; Chris@102: Chris@102: // If, at any point (in user code), singleton_default::instance() Chris@102: // is called, then the following function is instantiated. Chris@102: static object_type & instance() Chris@102: { Chris@102: // This is the object that we return a reference to. Chris@102: // It is guaranteed to be created before main() begins because of Chris@102: // the next line. Chris@102: static object_type obj; Chris@102: Chris@102: // The following line does nothing else than force the instantiation Chris@102: // of singleton_default::create_object, whose constructor is Chris@102: // called before main() begins. Chris@102: create_object.do_nothing(); Chris@102: Chris@102: return obj; Chris@102: } Chris@102: }; Chris@102: template Chris@102: typename singleton_default::object_creator Chris@102: singleton_default::create_object; Chris@102: Chris@102: } // namespace container_detail Chris@102: } // namespace container Chris@102: } // namespace boost Chris@102: Chris@102: #include Chris@102: Chris@102: #endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP