fix doc example typo
[boost.git] / boost / serialization / singleton.hpp
blobcca3b3eb00c658186438826655fc7ca57b618fc4
1 #ifndef BOOST_SERIALIZATION_SINGLETON_HPP
2 #define BOOST_SERIALIZATION_SINGLETON_HPP
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.
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
21 // c) non-locking
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)
34 # pragma once
35 #endif
37 #include <cassert>
38 #include <boost/noncopyable.hpp>
39 #include <boost/serialization/force_include.hpp>
41 namespace boost {
42 namespace serialization {
44 //////////////////////////////////////////////////////////////////////
45 // Provides a dynamically-initialized (singleton) instance of T in a
46 // way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or
47 // http://lists.boost.org/Archives/boost/2006/05/105286.php for
48 // details.
51 // singletons created by this code are guarenteed to be unique
52 // within the executable or shared library which creates them.
53 // This is sufficient and in fact ideal for the serialization library.
54 // The singleton is created when the module is loaded and destroyed
55 // when the module is unloaded.
57 // This base class has two functions.
59 // First it provides a module handle for each singleton indicating
60 // the executable or shared library in which it was created. This
61 // turns out to be necessary and sufficient to implement the tables
62 // used by serialization library.
64 // Second, it provides a mechanism to detect when a non-const function
65 // is called after initialization.
67 // make a singleton to lock/unlock all singletons for alteration.
68 // The intent is that all singletons created/used by this code
69 // are to be initialized before main is called. A test program
70 // can lock all the singletons when main is entereed. This any
71 // attempt to retieve a mutable instances while locked will
72 // generate a assertion if compiled for debug.
74 class singleton_module : public boost::noncopyable
76 private:
77 static bool & get_lock(){
78 static bool lock = false;
79 return lock;
81 public:
82 // static const void * get_module_handle(){
83 // return static_cast<const void *>(get_module_handle);
84 // }
85 static void lock(){
86 get_lock() = true;
88 static void unlock(){
89 get_lock() = false;
91 static bool is_locked() {
92 return get_lock();
96 namespace detail {
98 template<class T>
99 class singleton_wrapper : public T
101 public:
102 static bool m_is_destroyed;
103 ~singleton_wrapper(){
104 m_is_destroyed = true;
108 template<class T>
109 bool detail::singleton_wrapper<T>::m_is_destroyed = false;
111 } // detail
113 template <class T>
114 class singleton : public singleton_module
116 private:
117 BOOST_DLLEXPORT static T & instance;
118 // include this to provoke instantiation at pre-execution time
119 static void use(T const &) {}
120 BOOST_DLLEXPORT static T & get_instance() {
121 static detail::singleton_wrapper<T> t;
122 // refer to instance, causing it to be instantiated (and
123 // initialized at startup on working compilers)
124 assert(! detail::singleton_wrapper<T>::m_is_destroyed);
125 use(instance);
126 return static_cast<T &>(t);
128 public:
129 BOOST_DLLEXPORT static T & get_mutable_instance(){
130 assert(! is_locked());
131 return get_instance();
133 BOOST_DLLEXPORT static const T & get_const_instance(){
134 return get_instance();
136 BOOST_DLLEXPORT static bool is_destroyed(){
137 return detail::singleton_wrapper<T>::m_is_destroyed;
141 template<class T>
142 BOOST_DLLEXPORT T & singleton<T>::instance = singleton<T>::get_instance();
144 } // namespace serialization
145 } // namespace boost
147 #endif // BOOST_SERIALIZATION_SINGLETON_HPP