summaryrefslogtreecommitdiff
path: root/boost/serialization/singleton.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/serialization/singleton.hpp')
-rw-r--r--boost/serialization/singleton.hpp76
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