diff options
Diffstat (limited to 'boost/serialization/singleton.hpp')
-rw-r--r-- | boost/serialization/singleton.hpp | 76 |
1 files changed, 38 insertions, 38 deletions
diff --git a/boost/serialization/singleton.hpp b/boost/serialization/singleton.hpp index a40488c6df..b50afedbb9 100644 --- a/boost/serialization/singleton.hpp +++ b/boost/serialization/singleton.hpp @@ -81,65 +81,57 @@ namespace serialization { // attempt to retieve a mutable instances while locked will // generate a assertion if compiled for debug. +// note usage of BOOST_DLLEXPORT. These functions are in danger of +// being eliminated by the optimizer when building an application in +// release mode. Usage of the macro is meant to signal the compiler/linker +// to avoid dropping these functions which seem to be unreferenced. +// This usage is not related to autolinking. + class BOOST_SYMBOL_VISIBLE singleton_module : public boost::noncopyable { private: - BOOST_SERIALIZATION_DECL static bool & get_lock(); + BOOST_SERIALIZATION_DECL BOOST_DLLEXPORT static bool & get_lock() BOOST_USED; public: - static void lock(){ + BOOST_DLLEXPORT static void lock(){ get_lock() = true; } - - static void unlock(){ + BOOST_DLLEXPORT static void unlock(){ get_lock() = false; } - - static bool is_locked(){ + BOOST_DLLEXPORT static bool is_locked(){ return get_lock(); } }; -#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas - -namespace detail { - -template<class T> -class singleton_wrapper : public T -{ -public: - static bool m_is_destroyed; - ~singleton_wrapper(){ - m_is_destroyed = true; - } -}; - -template<class T> -bool detail::singleton_wrapper< T >::m_is_destroyed = false; - -} // detail - -// note usage of BOOST_DLLEXPORT. These functions are in danger of -// being eliminated by the optimizer when building an application in -// release mode. Usage of the macro is meant to signal the compiler/linker -// to avoid dropping these functions which seem to be unreferenced. -// This usage is not related to autolinking. - template <class T> class singleton : public singleton_module { private: - BOOST_DLLEXPORT static T & instance; + static T & m_instance; // include this to provoke instantiation at pre-execution time static void use(T const *) {} - BOOST_DLLEXPORT static T & get_instance() { - static detail::singleton_wrapper< T > t; + static T & get_instance() { + // use a wrapper so that types T with protected constructors + // can be used + class singleton_wrapper : public T {}; + static singleton_wrapper t; // refer to instance, causing it to be instantiated (and // initialized at startup on working compilers) - BOOST_ASSERT(! detail::singleton_wrapper< T >::m_is_destroyed); - use(& instance); + BOOST_ASSERT(! is_destroyed()); + // note that the following is absolutely essential. + // commenting out this statement will cause compilers to fail to + // construct the instance at pre-execution time. This would prevent + // our usage/implementation of "locking" and introduce uncertainty into + // the sequence of object initializaition. + use(& m_instance); return static_cast<T &>(t); } + static bool & get_is_destroyed(){ + static bool is_destroyed; + return is_destroyed; + } + public: BOOST_DLLEXPORT static T & get_mutable_instance(){ BOOST_ASSERT(! is_locked()); @@ -149,16 +141,24 @@ public: return get_instance(); } BOOST_DLLEXPORT static bool is_destroyed(){ - return detail::singleton_wrapper< T >::m_is_destroyed; + return get_is_destroyed(); + } + BOOST_DLLEXPORT singleton(){ + get_is_destroyed() = false; + } + BOOST_DLLEXPORT ~singleton() { + get_is_destroyed() = true; } }; template<class T> -BOOST_DLLEXPORT T & singleton< T >::instance = singleton< T >::get_instance(); +T & singleton< T >::m_instance = singleton< T >::get_instance(); } // namespace serialization } // namespace boost +#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas + #ifdef BOOST_MSVC #pragma warning(pop) #endif |