1 #ifndef BOOST_SERIALIZATION_SINGLETON_HPP
2 #define BOOST_SERIALIZATION_SINGLETON_HPP
4 /////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8
7 // Copyright David Abrahams 2006. Original version
9 // Copyright Robert Ramey 2007. Changes made to permit
10 // application throughout the serialization library.
12 // Distributed under the Boost
13 // Software License, Version 1.0. (See accompanying
14 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
16 // The intention here is to define a template which will convert
17 // any class into a singleton with the following features:
19 // a) initialized before first use.
20 // b) thread-safe for const access to the class
23 // In order to do this,
24 // a) Initialize dynamically when used.
25 // b) Require that all singletons be initialized before main
26 // is called or any entry point into the shared library is invoked.
27 // This guarentees no race condition for initialization.
28 // In debug mode, we assert that no non-const functions are called
29 // after main is invoked.
32 // MS compatible compilers support #pragma once
33 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
37 #include <boost/assert.hpp>
38 #include <boost/config.hpp>
39 #include <boost/noncopyable.hpp>
40 #include <boost/serialization/force_include.hpp>
43 # pragma warning(push)
44 # pragma warning(disable : 4511 4512)
48 namespace serialization
{
50 //////////////////////////////////////////////////////////////////////
51 // Provides a dynamically-initialized (singleton) instance of T in a
52 // way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or
53 // http://lists.boost.org/Archives/boost/2006/05/105286.php for
57 // singletons created by this code are guarenteed to be unique
58 // within the executable or shared library which creates them.
59 // This is sufficient and in fact ideal for the serialization library.
60 // The singleton is created when the module is loaded and destroyed
61 // when the module is unloaded.
63 // This base class has two functions.
65 // First it provides a module handle for each singleton indicating
66 // the executable or shared library in which it was created. This
67 // turns out to be necessary and sufficient to implement the tables
68 // used by serialization library.
70 // Second, it provides a mechanism to detect when a non-const function
71 // is called after initialization.
73 // make a singleton to lock/unlock all singletons for alteration.
74 // The intent is that all singletons created/used by this code
75 // are to be initialized before main is called. A test program
76 // can lock all the singletons when main is entereed. This any
77 // attempt to retieve a mutable instances while locked will
78 // generate a assertion if compiled for debug.
80 class singleton_module
:
81 public boost::noncopyable
84 static bool & get_lock(){
85 static bool lock
= false;
89 // static const void * get_module_handle(){
90 // return static_cast<const void *>(get_module_handle);
98 static bool is_locked() {
106 class singleton_wrapper
: public T
109 static bool m_is_destroyed
;
110 ~singleton_wrapper(){
111 m_is_destroyed
= true;
116 bool detail::singleton_wrapper
< T
>::m_is_destroyed
= false;
121 class singleton
: public singleton_module
124 BOOST_DLLEXPORT
static T
& instance
;
125 // include this to provoke instantiation at pre-execution time
126 static void use(T
const &) {}
127 BOOST_DLLEXPORT
static T
& get_instance() {
128 static detail::singleton_wrapper
< T
> t
;
129 // refer to instance, causing it to be instantiated (and
130 // initialized at startup on working compilers)
131 BOOST_ASSERT(! detail::singleton_wrapper
< T
>::m_is_destroyed
);
133 return static_cast<T
&>(t
);
136 BOOST_DLLEXPORT
static T
& get_mutable_instance(){
137 BOOST_ASSERT(! is_locked());
138 return get_instance();
140 BOOST_DLLEXPORT
static const T
& get_const_instance(){
141 return get_instance();
143 BOOST_DLLEXPORT
static bool is_destroyed(){
144 return detail::singleton_wrapper
< T
>::m_is_destroyed
;
149 BOOST_DLLEXPORT T
& singleton
< T
>::instance
= singleton
< T
>::get_instance();
151 } // namespace serialization
158 #endif // BOOST_SERIALIZATION_SINGLETON_HPP