1#ifndef BOOST_SERIALIZATION_SINGLETON_HPP
2#define BOOST_SERIALIZATION_SINGLETON_HPP
3
4/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8
5// singleton.hpp
6//
7// Copyright David Abrahams 2006. Original version
8//
9// Copyright Robert Ramey 2007. Changes made to permit
10// application throughout the serialization library.
11//
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)
15//
16// The intention here is to define a template which will convert
17// any class into a singleton with the following features:
18//
19// a) initialized before first use.
20// b) thread-safe for const access to the class
21// c) non-locking
22//
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.
30//
31
32// MS compatible compilers support #pragma once
33#if defined(_MSC_VER)
34# pragma once
35#endif
36
37#include <boost/assert.hpp>
38#include <boost/config.hpp>
39#include <boost/noncopyable.hpp>
40#include <boost/serialization/force_include.hpp>
41
42#ifdef BOOST_MSVC
43# pragma warning(push)
44# pragma warning(disable : 4511 4512)
45#endif
46
47namespace boost {
48namespace serialization {
49
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
54// details.
55//
56
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.
62
63// This base class has two functions.
64
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.
69
70// Second, it provides a mechanism to detect when a non-const function
71// is called after initialization.
72
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.
79
80class BOOST_SYMBOL_VISIBLE singleton_module :
81 public boost::noncopyable
82{
83private:
84 static bool & get_lock(){
85 static bool lock = false;
86 return lock;
87 }
88public:
89// static const void * get_module_handle(){
90// return static_cast<const void *>(get_module_handle);
91// }
92 static void lock(){
93 get_lock() = true;
94 }
95 static void unlock(){
96 get_lock() = false;
97 }
98 static bool is_locked() {
99 return get_lock();
100 }
101};
102
103namespace detail {
104
105template<class T>
106class singleton_wrapper : public T
107{
108public:
109 static bool m_is_destroyed;
110 ~singleton_wrapper(){
111 m_is_destroyed = true;
112 }
113};
114
115template<class T>
116bool detail::singleton_wrapper< T >::m_is_destroyed = false;
117
118} // detail
119
120template <class T>
121class singleton : public singleton_module
122{
123private:
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);
132 use(& instance);
133 return static_cast<T &>(t);
134 }
135public:
136 BOOST_DLLEXPORT static T & get_mutable_instance(){
137 BOOST_ASSERT(! is_locked());
138 return get_instance();
139 }
140 BOOST_DLLEXPORT static const T & get_const_instance(){
141 return get_instance();
142 }
143 BOOST_DLLEXPORT static bool is_destroyed(){
144 return detail::singleton_wrapper< T >::m_is_destroyed;
145 }
146};
147
148template<class T>
149BOOST_DLLEXPORT T & singleton< T >::instance = singleton< T >::get_instance();
150
151} // namespace serialization
152} // namespace boost
153
154#ifdef BOOST_MSVC
155#pragma warning(pop)
156#endif
157
158#endif // BOOST_SERIALIZATION_SINGLETON_HPP
159

source code of boost/boost/serialization/singleton.hpp