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