annotate DEPENDENCIES/generic/include/boost/serialization/singleton.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 #ifndef BOOST_SERIALIZATION_SINGLETON_HPP
Chris@16 2 #define BOOST_SERIALIZATION_SINGLETON_HPP
Chris@16 3
Chris@16 4 /////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8
Chris@16 5 // singleton.hpp
Chris@16 6 //
Chris@16 7 // Copyright David Abrahams 2006. Original version
Chris@16 8 //
Chris@16 9 // Copyright Robert Ramey 2007. Changes made to permit
Chris@16 10 // application throughout the serialization library.
Chris@16 11 //
Chris@16 12 // Distributed under the Boost
Chris@16 13 // Software License, Version 1.0. (See accompanying
Chris@16 14 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 15 //
Chris@16 16 // The intention here is to define a template which will convert
Chris@16 17 // any class into a singleton with the following features:
Chris@16 18 //
Chris@16 19 // a) initialized before first use.
Chris@16 20 // b) thread-safe for const access to the class
Chris@16 21 // c) non-locking
Chris@16 22 //
Chris@16 23 // In order to do this,
Chris@16 24 // a) Initialize dynamically when used.
Chris@16 25 // b) Require that all singletons be initialized before main
Chris@16 26 // is called or any entry point into the shared library is invoked.
Chris@16 27 // This guarentees no race condition for initialization.
Chris@16 28 // In debug mode, we assert that no non-const functions are called
Chris@16 29 // after main is invoked.
Chris@16 30 //
Chris@16 31
Chris@16 32 // MS compatible compilers support #pragma once
Chris@101 33 #if defined(_MSC_VER)
Chris@16 34 # pragma once
Chris@16 35 #endif
Chris@16 36
Chris@16 37 #include <boost/assert.hpp>
Chris@16 38 #include <boost/config.hpp>
Chris@16 39 #include <boost/noncopyable.hpp>
Chris@16 40 #include <boost/serialization/force_include.hpp>
Chris@16 41
Chris@16 42 #ifdef BOOST_MSVC
Chris@16 43 # pragma warning(push)
Chris@16 44 # pragma warning(disable : 4511 4512)
Chris@16 45 #endif
Chris@16 46
Chris@16 47 namespace boost {
Chris@16 48 namespace serialization {
Chris@16 49
Chris@16 50 //////////////////////////////////////////////////////////////////////
Chris@16 51 // Provides a dynamically-initialized (singleton) instance of T in a
Chris@16 52 // way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or
Chris@16 53 // http://lists.boost.org/Archives/boost/2006/05/105286.php for
Chris@16 54 // details.
Chris@16 55 //
Chris@16 56
Chris@16 57 // singletons created by this code are guarenteed to be unique
Chris@16 58 // within the executable or shared library which creates them.
Chris@16 59 // This is sufficient and in fact ideal for the serialization library.
Chris@16 60 // The singleton is created when the module is loaded and destroyed
Chris@16 61 // when the module is unloaded.
Chris@16 62
Chris@16 63 // This base class has two functions.
Chris@16 64
Chris@16 65 // First it provides a module handle for each singleton indicating
Chris@16 66 // the executable or shared library in which it was created. This
Chris@16 67 // turns out to be necessary and sufficient to implement the tables
Chris@16 68 // used by serialization library.
Chris@16 69
Chris@16 70 // Second, it provides a mechanism to detect when a non-const function
Chris@16 71 // is called after initialization.
Chris@16 72
Chris@16 73 // make a singleton to lock/unlock all singletons for alteration.
Chris@16 74 // The intent is that all singletons created/used by this code
Chris@16 75 // are to be initialized before main is called. A test program
Chris@16 76 // can lock all the singletons when main is entereed. This any
Chris@16 77 // attempt to retieve a mutable instances while locked will
Chris@16 78 // generate a assertion if compiled for debug.
Chris@16 79
Chris@16 80 class singleton_module :
Chris@16 81 public boost::noncopyable
Chris@16 82 {
Chris@16 83 private:
Chris@16 84 static bool & get_lock(){
Chris@16 85 static bool lock = false;
Chris@16 86 return lock;
Chris@16 87 }
Chris@16 88 public:
Chris@16 89 // static const void * get_module_handle(){
Chris@16 90 // return static_cast<const void *>(get_module_handle);
Chris@16 91 // }
Chris@16 92 static void lock(){
Chris@16 93 get_lock() = true;
Chris@16 94 }
Chris@16 95 static void unlock(){
Chris@16 96 get_lock() = false;
Chris@16 97 }
Chris@16 98 static bool is_locked() {
Chris@16 99 return get_lock();
Chris@16 100 }
Chris@16 101 };
Chris@16 102
Chris@16 103 namespace detail {
Chris@16 104
Chris@16 105 template<class T>
Chris@16 106 class singleton_wrapper : public T
Chris@16 107 {
Chris@16 108 public:
Chris@16 109 static bool m_is_destroyed;
Chris@16 110 ~singleton_wrapper(){
Chris@16 111 m_is_destroyed = true;
Chris@16 112 }
Chris@16 113 };
Chris@16 114
Chris@16 115 template<class T>
Chris@16 116 bool detail::singleton_wrapper< T >::m_is_destroyed = false;
Chris@16 117
Chris@16 118 } // detail
Chris@16 119
Chris@16 120 template <class T>
Chris@16 121 class singleton : public singleton_module
Chris@16 122 {
Chris@16 123 private:
Chris@16 124 BOOST_DLLEXPORT static T & instance;
Chris@16 125 // include this to provoke instantiation at pre-execution time
Chris@16 126 static void use(T const &) {}
Chris@16 127 BOOST_DLLEXPORT static T & get_instance() {
Chris@16 128 static detail::singleton_wrapper< T > t;
Chris@16 129 // refer to instance, causing it to be instantiated (and
Chris@16 130 // initialized at startup on working compilers)
Chris@16 131 BOOST_ASSERT(! detail::singleton_wrapper< T >::m_is_destroyed);
Chris@16 132 use(instance);
Chris@16 133 return static_cast<T &>(t);
Chris@16 134 }
Chris@16 135 public:
Chris@16 136 BOOST_DLLEXPORT static T & get_mutable_instance(){
Chris@16 137 BOOST_ASSERT(! is_locked());
Chris@16 138 return get_instance();
Chris@16 139 }
Chris@16 140 BOOST_DLLEXPORT static const T & get_const_instance(){
Chris@16 141 return get_instance();
Chris@16 142 }
Chris@16 143 BOOST_DLLEXPORT static bool is_destroyed(){
Chris@16 144 return detail::singleton_wrapper< T >::m_is_destroyed;
Chris@16 145 }
Chris@16 146 };
Chris@16 147
Chris@16 148 template<class T>
Chris@16 149 BOOST_DLLEXPORT T & singleton< T >::instance = singleton< T >::get_instance();
Chris@16 150
Chris@16 151 } // namespace serialization
Chris@16 152 } // namespace boost
Chris@16 153
Chris@16 154 #ifdef BOOST_MSVC
Chris@16 155 #pragma warning(pop)
Chris@16 156 #endif
Chris@16 157
Chris@16 158 #endif // BOOST_SERIALIZATION_SINGLETON_HPP