summaryrefslogtreecommitdiff
path: root/shared/loki/Singleton.h
diff options
context:
space:
mode:
Diffstat (limited to 'shared/loki/Singleton.h')
-rw-r--r--shared/loki/Singleton.h1426
1 files changed, 713 insertions, 713 deletions
diff --git a/shared/loki/Singleton.h b/shared/loki/Singleton.h
index 42d6eb0d..40cc7550 100644
--- a/shared/loki/Singleton.h
+++ b/shared/loki/Singleton.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SINGLETON_INC_
@@ -30,9 +30,9 @@
#include <memory>
#ifdef _MSC_VER
-#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
+#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
#else
-#define LOKI_C_CALLING_CONVENTION_QUALIFIER
+#define LOKI_C_CALLING_CONVENTION_QUALIFIER
#endif
/// \defgroup SingletonGroup Singleton
@@ -42,7 +42,7 @@
/// \ingroup SingletonGroup
/// The lifetimes of the singleton.
/// \par Special lifetime for SmallObjects
-/// When the holded object is a Small(Value)Object or the holded object
+/// When the holded object is a Small(Value)Object or the holded object
/// uses objects which are or inherit from Small(Value)Object
/// then you can't use the default lifetime: you must use the lifetime
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
@@ -52,820 +52,820 @@
namespace Loki
{
- typedef void (LOKI_C_CALLING_CONVENTION_QUALIFIER *atexit_pfn_t)();
+typedef void (LOKI_C_CALLING_CONVENTION_QUALIFIER* atexit_pfn_t)();
- namespace Private
- {
+namespace Private
+{
#ifndef LOKI_MAKE_DLL
- void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
+void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
#else
- void LOKI_EXPORT AtExitFn();
+void LOKI_EXPORT AtExitFn();
#endif
- class LifetimeTracker;
+class LifetimeTracker;
-#define LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
+#define LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
- // Helper data
- // std::list because of the inserts
- typedef std::list<LifetimeTracker*> TrackerArray;
- extern LOKI_EXPORT TrackerArray* pTrackerArray;
+// Helper data
+// std::list because of the inserts
+typedef std::list<LifetimeTracker*> TrackerArray;
+extern LOKI_EXPORT TrackerArray* pTrackerArray;
#else
- // Helper data
- typedef LifetimeTracker** TrackerArray;
- extern TrackerArray pTrackerArray;
- extern unsigned int elements;
+// Helper data
+typedef LifetimeTracker** TrackerArray;
+extern TrackerArray pTrackerArray;
+extern unsigned int elements;
#endif
- ////////////////////////////////////////////////////////////////////////////////
- // class LifetimeTracker
- // Helper class for SetLongevity
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// class LifetimeTracker
+// Helper class for SetLongevity
+////////////////////////////////////////////////////////////////////////////////
- class LifetimeTracker
- {
- public:
- LifetimeTracker(unsigned int x) : longevity_(x)
- {}
-
- virtual ~LifetimeTracker() = 0;
-
- static bool Compare(const LifetimeTracker* lhs,
- const LifetimeTracker* rhs)
- {
- return lhs->longevity_ > rhs->longevity_;
- }
-
- private:
- unsigned int longevity_;
- };
-
- // Definition required
- inline LifetimeTracker::~LifetimeTracker() {}
+class LifetimeTracker
+{
+public:
+ LifetimeTracker(unsigned int x) : longevity_(x)
+ {}
- // Helper destroyer function
- template <typename T>
- struct Deleter
- {
- typedef void (*Type)(T*);
- static void Delete(T* pObj)
- { delete pObj; }
- };
+ virtual ~LifetimeTracker() = 0;
- // Concrete lifetime tracker for objects of type T
- template <typename T, typename Destroyer>
- class ConcreteLifetimeTracker : public LifetimeTracker
- {
- public:
- ConcreteLifetimeTracker(T* p,unsigned int longevity, Destroyer d)
- : LifetimeTracker(longevity)
- , pTracked_(p)
- , destroyer_(d)
- {}
-
- ~ConcreteLifetimeTracker()
- { destroyer_(pTracked_); }
-
- private:
- T* pTracked_;
- Destroyer destroyer_;
- };
+ static bool Compare(const LifetimeTracker* lhs,
+ const LifetimeTracker* rhs)
+ {
+ return lhs->longevity_ > rhs->longevity_;
+ }
- } // namespace Private
+private:
+ unsigned int longevity_;
+};
- ////////////////////////////////////////////////////////////////////////////////
- /// \ingroup LifetimeGroup
- ///
- /// Assigns an object a longevity; ensures ordered destructions of objects
- /// registered thusly during the exit sequence of the application
- ////////////////////////////////////////////////////////////////////////////////
+// Definition required
+inline LifetimeTracker::~LifetimeTracker() {}
+
+// Helper destroyer function
+template <typename T>
+struct Deleter
+{
+ typedef void (*Type)(T*);
+ static void Delete(T* pObj)
+ { delete pObj; }
+};
+
+// Concrete lifetime tracker for objects of type T
+template <typename T, typename Destroyer>
+class ConcreteLifetimeTracker : public LifetimeTracker
+{
+public:
+ ConcreteLifetimeTracker(T* p,unsigned int longevity, Destroyer d)
+ : LifetimeTracker(longevity)
+ , pTracked_(p)
+ , destroyer_(d)
+ {}
+
+ ~ConcreteLifetimeTracker()
+ { destroyer_(pTracked_); }
+
+private:
+ T* pTracked_;
+ Destroyer destroyer_;
+};
+
+} // namespace Private
+
+////////////////////////////////////////////////////////////////////////////////
+/// \ingroup LifetimeGroup
+///
+/// Assigns an object a longevity; ensures ordered destructions of objects
+/// registered thusly during the exit sequence of the application
+////////////////////////////////////////////////////////////////////////////////
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
- template <typename T, typename Destroyer>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- Destroyer d)
- {
- using namespace Private;
-
- // manage lifetime of stack manually
- if(pTrackerArray==0)
- pTrackerArray = new TrackerArray;
-
- // automatically delete the ConcreteLifetimeTracker object when a exception is thrown
- std::auto_ptr<LifetimeTracker>
- p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) );
-
- // Find correct position
- TrackerArray::iterator pos = std::upper_bound(
- pTrackerArray->begin(),
- pTrackerArray->end(),
- p.get(),
- LifetimeTracker::Compare);
-
- // Insert the pointer to the ConcreteLifetimeTracker object into the queue
- pTrackerArray->insert(pos, p.get());
-
- // nothing has thrown: don't delete the ConcreteLifetimeTracker object
- p.release();
-
- // Register a call to AtExitFn
- std::atexit(Private::AtExitFn);
- }
+template <typename T, typename Destroyer>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ Destroyer d)
+{
+ using namespace Private;
+
+ // manage lifetime of stack manually
+ if(pTrackerArray==0)
+ pTrackerArray = new TrackerArray;
+
+ // automatically delete the ConcreteLifetimeTracker object when a exception is thrown
+ std::auto_ptr<LifetimeTracker>
+ p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) );
+
+ // Find correct position
+ TrackerArray::iterator pos = std::upper_bound(
+ pTrackerArray->begin(),
+ pTrackerArray->end(),
+ p.get(),
+ LifetimeTracker::Compare);
+
+ // Insert the pointer to the ConcreteLifetimeTracker object into the queue
+ pTrackerArray->insert(pos, p.get());
+
+ // nothing has thrown: don't delete the ConcreteLifetimeTracker object
+ p.release();
+
+ // Register a call to AtExitFn
+ std::atexit(Private::AtExitFn);
+}
#else
-
- template <typename T, typename Destroyer>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- Destroyer d)
- {
- using namespace Private;
-
- TrackerArray pNewArray = static_cast<TrackerArray>(
- std::realloc(pTrackerArray,
- sizeof(*pTrackerArray) * (elements + 1)));
- if (!pNewArray) throw std::bad_alloc();
-
- // Delayed assignment for exception safety
- pTrackerArray = pNewArray;
-
- LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
- pDynObject, longevity, d);
-
- // Insert a pointer to the object into the queue
- TrackerArray pos = std::upper_bound(
- pTrackerArray,
- pTrackerArray + elements,
- p,
- LifetimeTracker::Compare);
- std::copy_backward(
- pos,
- pTrackerArray + elements,
- pTrackerArray + elements + 1);
- *pos = p;
- ++elements;
-
- // Register a call to AtExitFn
- std::atexit(Private::AtExitFn);
- }
+
+template <typename T, typename Destroyer>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ Destroyer d)
+{
+ using namespace Private;
+
+ TrackerArray pNewArray = static_cast<TrackerArray>(
+ std::realloc(pTrackerArray,
+ sizeof(*pTrackerArray) * (elements + 1)));
+ if (!pNewArray) throw std::bad_alloc();
+
+ // Delayed assignment for exception safety
+ pTrackerArray = pNewArray;
+
+ LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
+ pDynObject, longevity, d);
+
+ // Insert a pointer to the object into the queue
+ TrackerArray pos = std::upper_bound(
+ pTrackerArray,
+ pTrackerArray + elements,
+ p,
+ LifetimeTracker::Compare);
+ std::copy_backward(
+ pos,
+ pTrackerArray + elements,
+ pTrackerArray + elements + 1);
+ *pos = p;
+ ++elements;
+
+ // Register a call to AtExitFn
+ std::atexit(Private::AtExitFn);
+}
#endif
- template <typename T>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
- {
- SetLongevity<T, typename Private::Deleter<T>::Type>(pDynObject, longevity, d);
- }
+template <typename T>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
+{
+ SetLongevity<T, typename Private::Deleter<T>::Type>(pDynObject, longevity, d);
+}
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsingNew
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a straight call to the new operator
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateUsingNew
- {
- static T* Create()
- { return new T; }
-
- static void Destroy(T* p)
- { delete p; }
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsing
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a custom allocater.
- /// Usage: e.g. CreateUsing<std::allocator>::Allocator
- ////////////////////////////////////////////////////////////////////////////////
- template<template<class> class Alloc>
- struct CreateUsing
- {
- template <class T>
- struct Allocator
- {
- static Alloc<T> allocator;
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsingNew
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a straight call to the new operator
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateUsingNew
+{
+ static T* Create()
+ { return new T; }
- static T* Create()
- {
- return new (allocator.allocate(1)) T;
- }
+ static void Destroy(T* p)
+ { delete p; }
+};
- static void Destroy(T* p)
- {
- //allocator.destroy(p);
- p->~T();
- allocator.deallocate(p,1);
- }
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsingMalloc
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a call to std::malloc, followed by a call to the
- /// placement new operator
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateUsingMalloc
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsing
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a custom allocater.
+/// Usage: e.g. CreateUsing<std::allocator>::Allocator
+////////////////////////////////////////////////////////////////////////////////
+template<template<class> class Alloc>
+struct CreateUsing
+{
+ template <class T>
+ struct Allocator
{
+ static Alloc<T> allocator;
+
static T* Create()
{
- void* p = std::malloc(sizeof(T));
- if (!p) return 0;
- return new(p) T;
+ return new (allocator.allocate(1)) T;
}
-
+
static void Destroy(T* p)
{
+ //allocator.destroy(p);
p->~T();
- std::free(p);
+ allocator.deallocate(p,1);
}
};
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateStatic
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates an object in static memory
- /// Implementation is slightly nonportable because it uses the MaxAlign trick
- /// (an union of all types to ensure proper memory alignment). This trick is
- /// nonportable in theory but highly portable in practice.
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateStatic
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsingMalloc
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a call to std::malloc, followed by a call to the
+/// placement new operator
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateUsingMalloc
+{
+ static T* Create()
{
-
+ void* p = std::malloc(sizeof(T));
+ if (!p) return 0;
+ return new(p) T;
+ }
+
+ static void Destroy(T* p)
+ {
+ p->~T();
+ std::free(p);
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateStatic
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates an object in static memory
+/// Implementation is slightly nonportable because it uses the MaxAlign trick
+/// (an union of all types to ensure proper memory alignment). This trick is
+/// nonportable in theory but highly portable in practice.
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateStatic
+{
+
#ifdef _MSC_VER
-#pragma warning( push )
+#pragma warning( push )
#pragma warning( disable : 4121 )
-// alignment of a member was sensitive to packing
+ // alignment of a member was sensitive to packing
#endif // _MSC_VER
- union MaxAlign
- {
- char t_[sizeof(T)];
- short int shortInt_;
- int int_;
- long int longInt_;
- float float_;
- double double_;
- long double longDouble_;
- struct Test;
- int Test::* pMember_;
- int (Test::*pMemberFn_)(int);
- };
-
+ union MaxAlign
+ {
+ char t_[sizeof(T)];
+ short int shortInt_;
+ int int_;
+ long int longInt_;
+ float float_;
+ double double_;
+ long double longDouble_;
+ struct Test;
+ int Test::* pMember_;
+ int (Test::*pMemberFn_)(int);
+ };
+
#ifdef _MSC_VER
#pragma warning( pop )
#endif // _MSC_VER
-
- static T* Create()
- {
- static MaxAlign staticMemory_;
- return new(&staticMemory_) T;
- }
-
- static void Destroy(T* p)
- {
- p->~T();
- }
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct DefaultLifetime
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction as per C++ rules
- /// Forwards to std::atexit
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- struct DefaultLifetime
+ static T* Create()
{
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- { std::atexit(pFun); }
-
- static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
- };
+ static MaxAlign staticMemory_;
+ return new(&staticMemory_) T;
+ }
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct PhoenixSingleton
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction as per C++ rules, and it allows object
- /// recreation by not throwing an exception from OnDeadReference
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class PhoenixSingleton
+ static void Destroy(T* p)
+ {
+ p->~T();
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct DefaultLifetime
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction as per C++ rules
+/// Forwards to std::atexit
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+struct DefaultLifetime
+{
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
+ { std::atexit(pFun); }
+
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct PhoenixSingleton
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction as per C++ rules, and it allows object
+/// recreation by not throwing an exception from OnDeadReference
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class PhoenixSingleton
+{
+public:
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
{
- public:
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- {
#ifndef ATEXIT_FIXED
- if (!destroyedOnce_)
+ if (!destroyedOnce_)
#endif
- std::atexit(pFun);
- }
-
- static void OnDeadReference()
- {
+ std::atexit(pFun);
+ }
+
+ static void OnDeadReference()
+ {
#ifndef ATEXIT_FIXED
- destroyedOnce_ = true;
+ destroyedOnce_ = true;
#endif
- }
-
- private:
+ }
+
+private:
#ifndef ATEXIT_FIXED
- static bool destroyedOnce_;
+ static bool destroyedOnce_;
#endif
- };
-
+};
+
#ifndef ATEXIT_FIXED
- template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
+template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
#endif
- ////////////////////////////////////////////////////////////////////////////////
- // Copyright (c) 2004 by Curtis Krauskopf - curtis@decompile.com
- ///
- /// \struct DeletableSingleton
- ///
- /// \ingroup LifetimeGroup
- ///
- /// A DeletableSingleton allows the instantiated singleton to be
- /// destroyed at any time. The singleton can be reinstantiated at
- /// any time, even during program termination.
- /// If the singleton exists when the program terminates, it will
- /// be automatically deleted.
- ///
- /// \par Usage:
- /// The singleton can be deleted manually:
- ///
- /// DeletableSingleton<MyClass>::GracefulDelete();
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class DeletableSingleton
- {
- public:
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2004 by Curtis Krauskopf - curtis@decompile.com
+///
+/// \struct DeletableSingleton
+///
+/// \ingroup LifetimeGroup
+///
+/// A DeletableSingleton allows the instantiated singleton to be
+/// destroyed at any time. The singleton can be reinstantiated at
+/// any time, even during program termination.
+/// If the singleton exists when the program terminates, it will
+/// be automatically deleted.
+///
+/// \par Usage:
+/// The singleton can be deleted manually:
+///
+/// DeletableSingleton<MyClass>::GracefulDelete();
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class DeletableSingleton
+{
+public:
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- {
- static bool firstPass = true;
- isDead = false;
- deleter = pFun;
- if (firstPass || needCallback)
- {
- std::atexit(atexitCallback);
- firstPass = false;
- needCallback = false;
- }
- }
-
- static void OnDeadReference()
- {
- }
- /// delete singleton object manually
- static void GracefulDelete()
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
+ {
+ static bool firstPass = true;
+ isDead = false;
+ deleter = pFun;
+ if (firstPass || needCallback)
{
- if (isDead)
- return;
- isDead = true;
- deleter();
+ std::atexit(atexitCallback);
+ firstPass = false;
+ needCallback = false;
}
-
- protected:
- static atexit_pfn_t deleter;
- static bool isDead;
- static bool needCallback;
-
- static void atexitCallback()
- {
+ }
+
+ static void OnDeadReference()
+ {
+ }
+ /// delete singleton object manually
+ static void GracefulDelete()
+ {
+ if (isDead)
+ return;
+ isDead = true;
+ deleter();
+ }
+
+protected:
+ static atexit_pfn_t deleter;
+ static bool isDead;
+ static bool needCallback;
+
+ static void atexitCallback()
+ {
#ifdef ATEXIT_FIXED
- needCallback = true;
+ needCallback = true;
#else
- needCallback = false;
+ needCallback = false;
#endif
- GracefulDelete();
- }
- };
-
- template <class T>
- atexit_pfn_t DeletableSingleton<T>::deleter = 0;
-
- template <class T>
- bool DeletableSingleton<T>::isDead = true;
-
- template <class T>
- bool DeletableSingleton<T>::needCallback = true;
+ GracefulDelete();
+ }
+};
+
+template <class T>
+atexit_pfn_t DeletableSingleton<T>::deleter = 0;
+
+template <class T>
+bool DeletableSingleton<T>::isDead = true;
+
+template <class T>
+bool DeletableSingleton<T>::needCallback = true;
- ////////////////////////////////////////////////////////////////////////////////
- // class template Adapter
- // Helper for SingletonWithLongevity below
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// class template Adapter
+// Helper for SingletonWithLongevity below
+////////////////////////////////////////////////////////////////////////////////
+
+namespace Private
+{
+template <class T>
+struct Adapter
+{
+ void operator()(T*) { return pFun_(); }
+ atexit_pfn_t pFun_;
+};
+}
- namespace Private
+////////////////////////////////////////////////////////////////////////////////
+/// \struct SingletonWithLongevity
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction in order of their longevities
+/// Assumes a visible function GetLongevity(T*) that returns the longevity of the
+/// object.
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class SingletonWithLongevity
+{
+public:
+ static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
{
- template <class T>
- struct Adapter
- {
- void operator()(T*) { return pFun_(); }
- atexit_pfn_t pFun_;
- };
+ Private::Adapter<T> adapter = { pFun };
+ SetLongevity(pObj, GetLongevity(pObj), adapter);
}
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct SingletonWithLongevity
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction in order of their longevities
- /// Assumes a visible function GetLongevity(T*) that returns the longevity of the
- /// object.
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class SingletonWithLongevity
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct NoDestroy
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Never destroys the object
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+struct NoDestroy
+{
+ static void ScheduleDestruction(T*, atexit_pfn_t)
+ {}
+
+ static void OnDeadReference()
+ {}
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \defgroup LongevityLifetimeGroup LongevityLifetime
+/// \ingroup LifetimeGroup
+///
+/// \namespace LongevityLifetime
+///
+/// \ingroup LongevityLifetimeGroup
+/// \brief In this namespace are special lifetime policies to manage lifetime
+/// dependencies.
+////////////////////////////////////////////////////////////////////////////////
+namespace LongevityLifetime
+{
+////////////////////////////////////////////////////////////////////////////////
+/// \struct SingletonFixedLongevity
+///
+/// \ingroup LongevityLifetimeGroup
+/// Add your own lifetimes into the namespace 'LongevityLifetime'
+/// with your prefered lifetime by adding a struct like this:
+///
+/// template<class T>
+/// struct MyLifetime : SingletonFixedLongevity< MyLifetimeNumber ,T> {}
+////////////////////////////////////////////////////////////////////////////////
+template <unsigned int Longevity, class T>
+class SingletonFixedLongevity
+{
+public:
+ virtual ~SingletonFixedLongevity() {}
+
+ static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ {
+ Private::Adapter<T> adapter = { pFun };
+ SetLongevity(pObj, Longevity , adapter);
+ }
+
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+/// \struct DieLast
+/// \ingroup LongevityLifetimeGroup
+/// \brief Longest possible SingletonWithLongevity lifetime: 0xFFFFFFFF
+template <class T>
+struct DieLast : SingletonFixedLongevity<0xFFFFFFFF ,T>
+ {};
+
+/// \struct DieDirectlyBeforeLast
+/// \ingroup LongevityLifetimeGroup
+/// \brief Lifetime is a one less than DieLast: 0xFFFFFFFF-1
+template <class T>
+struct DieDirectlyBeforeLast : SingletonFixedLongevity<0xFFFFFFFF-1 ,T>
+ {};
+
+/// \struct DieFirst
+/// \ingroup LongevityLifetimeGroup
+/// \brief Shortest possible SingletonWithLongevity lifetime: 0
+template <class T>
+struct DieFirst : SingletonFixedLongevity<0,T>
+ {};
+
+}//namespace LongevityLifetime
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class FollowIntoDeath
+///
+/// \ingroup LifetimeGroup
+///
+/// Lifetime policyfor the SingletonHolder tempalte.
+/// Followers will die after the master dies Followers will not die, if
+/// - master never dies (NoDestroy policy)
+/// - master never created
+/// - master dies not in the function registered with atexit
+/// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete)
+///
+/// \par Usage:
+///
+/// Lifetimes of the master and the follower singletons, e.g. with a M and a F class:
+/// \code SingletonHolder< M , FollowIntoDeath::With<DefaultLifetime>::AsMasterLifetime > MasterSingleton; \endcode
+/// \code SingletonHolder< F , CreateUsingNew, FollowIntoDeath::AfterMaster< MasterSingleton >::IsDestroyed > FollowerSingleton \endcode
+////////////////////////////////////////////////////////////////////////////////
+class FollowIntoDeath
+{
+ template<class T>
+ class Followers
{
+ typedef std::vector<atexit_pfn_t> Container;
+ typedef typename Container::iterator iterator;
+ static Container* followers_;
+
public:
- static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ static void Init()
+ {
+ static bool done = false;
+ if(!done)
+ {
+ followers_ = new Container;
+ done = true;
+ }
+ }
+
+ static void AddFollower(atexit_pfn_t ae)
{
- Private::Adapter<T> adapter = { pFun };
- SetLongevity(pObj, GetLongevity(pObj), adapter);
+ Init();
+ followers_->push_back(ae);
}
-
- static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct NoDestroy
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Never destroys the object
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- struct NoDestroy
- {
- static void ScheduleDestruction(T*, atexit_pfn_t)
- {}
-
- static void OnDeadReference()
- {}
+ static void DestroyFollowers()
+ {
+ Init();
+ for(iterator it = followers_->begin(); it != followers_->end(); ++it)
+ (*it)();
+ delete followers_;
+ }
};
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \defgroup LongevityLifetimeGroup LongevityLifetime
- /// \ingroup LifetimeGroup
- ///
- /// \namespace LongevityLifetime
- ///
- /// \ingroup LongevityLifetimeGroup
- /// \brief In this namespace are special lifetime policies to manage lifetime
- /// dependencies.
- ////////////////////////////////////////////////////////////////////////////////
- namespace LongevityLifetime
+
+public:
+
+ /// \struct With
+ /// Template for the master
+ /// \param Lifetime Lifetime policy for the master
+ template<template <class> class Lifetime>
+ struct With
{
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct SingletonFixedLongevity
- ///
- /// \ingroup LongevityLifetimeGroup
- /// Add your own lifetimes into the namespace 'LongevityLifetime'
- /// with your prefered lifetime by adding a struct like this:
- ///
- /// template<class T>
- /// struct MyLifetime : SingletonFixedLongevity< MyLifetimeNumber ,T> {}
- ////////////////////////////////////////////////////////////////////////////////
- template <unsigned int Longevity, class T>
- class SingletonFixedLongevity
+ /// \struct AsMasterLifetime
+ /// Policy for master
+ template<class Master>
+ struct AsMasterLifetime
{
- public:
- virtual ~SingletonFixedLongevity() {}
-
- static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ static void ScheduleDestruction(Master* pObj, atexit_pfn_t pFun)
{
- Private::Adapter<T> adapter = { pFun };
- SetLongevity(pObj, Longevity , adapter);
+ Followers<Master>::Init();
+ Lifetime<Master>::ScheduleDestruction(pObj, pFun);
+
+ // use same policy for the followers and force a new
+ // template instantiation, this adds a additional atexit entry
+ // does not work with SetLonlevity, but there you can control
+ // the lifetime with the GetLongevity function.
+ Lifetime<Followers<Master> >::ScheduleDestruction(0,Followers<Master>::DestroyFollowers);
}
-
+
static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
+ {
+ throw std::logic_error("Dead Reference Detected");
+ }
};
+ };
- /// \struct DieLast
- /// \ingroup LongevityLifetimeGroup
- /// \brief Longest possible SingletonWithLongevity lifetime: 0xFFFFFFFF
- template <class T>
- struct DieLast : SingletonFixedLongevity<0xFFFFFFFF ,T>
- {};
-
- /// \struct DieDirectlyBeforeLast
- /// \ingroup LongevityLifetimeGroup
- /// \brief Lifetime is a one less than DieLast: 0xFFFFFFFF-1
- template <class T>
- struct DieDirectlyBeforeLast : SingletonFixedLongevity<0xFFFFFFFF-1 ,T>
- {};
-
- /// \struct DieFirst
- /// \ingroup LongevityLifetimeGroup
- /// \brief Shortest possible SingletonWithLongevity lifetime: 0
- template <class T>
- struct DieFirst : SingletonFixedLongevity<0,T>
- {};
-
- }//namespace LongevityLifetime
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class FollowIntoDeath
- ///
- /// \ingroup LifetimeGroup
- ///
- /// Lifetime policyfor the SingletonHolder tempalte.
- /// Followers will die after the master dies Followers will not die, if
- /// - master never dies (NoDestroy policy)
- /// - master never created
- /// - master dies not in the function registered with atexit
- /// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete)
- ///
- /// \par Usage:
- ///
- /// Lifetimes of the master and the follower singletons, e.g. with a M and a F class:
- /// \code SingletonHolder< M , FollowIntoDeath::With<DefaultLifetime>::AsMasterLifetime > MasterSingleton; \endcode
- /// \code SingletonHolder< F , CreateUsingNew, FollowIntoDeath::AfterMaster< MasterSingleton >::IsDestroyed > FollowerSingleton \endcode
- ////////////////////////////////////////////////////////////////////////////////
- class FollowIntoDeath
+ /// \struct AfterMaster
+ /// Template for the follower
+ /// \param Master Master to follow into death
+ template<class Master>
+ struct AfterMaster
{
- template<class T>
- class Followers
+ /// \struct IsDestroyed
+ /// Policy for followers
+ template<class F>
+ struct IsDestroyed
{
- typedef std::vector<atexit_pfn_t> Container;
- typedef typename Container::iterator iterator;
- static Container* followers_;
-
- public:
- static void Init()
+ static void ScheduleDestruction(F*, atexit_pfn_t pFun)
{
- static bool done = false;
- if(!done)
- {
- followers_ = new Container;
- done = true;
- }
+ Followers<Master>::AddFollower(pFun);
}
- static void AddFollower(atexit_pfn_t ae)
- {
- Init();
- followers_->push_back(ae);
- }
-
- static void DestroyFollowers()
+ static void OnDeadReference()
{
- Init();
- for(iterator it = followers_->begin();it != followers_->end();++it)
- (*it)();
- delete followers_;
+ throw std::logic_error("Dead Reference Detected");
}
};
+ };
+};
- public:
+template<class T>
+typename FollowIntoDeath::Followers<T>::Container*
+FollowIntoDeath::Followers<T>::followers_ = 0;
- /// \struct With
- /// Template for the master
- /// \param Lifetime Lifetime policy for the master
- template<template <class> class Lifetime>
- struct With
- {
- /// \struct AsMasterLifetime
- /// Policy for master
- template<class Master>
- struct AsMasterLifetime
- {
- static void ScheduleDestruction(Master* pObj, atexit_pfn_t pFun)
- {
- Followers<Master>::Init();
- Lifetime<Master>::ScheduleDestruction(pObj, pFun);
-
- // use same policy for the followers and force a new
- // template instantiation, this adds a additional atexit entry
- // does not work with SetLonlevity, but there you can control
- // the lifetime with the GetLongevity function.
- Lifetime<Followers<Master> >::ScheduleDestruction(0,Followers<Master>::DestroyFollowers);
- }
-
- static void OnDeadReference()
- {
- throw std::logic_error("Dead Reference Detected");
- }
- };
- };
- /// \struct AfterMaster
- /// Template for the follower
- /// \param Master Master to follow into death
- template<class Master>
- struct AfterMaster
- {
- /// \struct IsDestroyed
- /// Policy for followers
- template<class F>
- struct IsDestroyed
- {
- static void ScheduleDestruction(F*, atexit_pfn_t pFun)
- {
- Followers<Master>::AddFollower(pFun);
- }
-
- static void OnDeadReference()
- {
- throw std::logic_error("Dead Reference Detected");
- }
- };
- };
- };
- template<class T>
- typename FollowIntoDeath::Followers<T>::Container*
- FollowIntoDeath::Followers<T>::followers_ = 0;
-
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class SingletonHolder
- ///
- /// \ingroup SingletonGroup
- ///
- /// Provides Singleton amenities for a type T
- /// To protect that type from spurious instantiations,
- /// you have to protect it yourself.
- ///
- /// \param CreationPolicy Creation policy, default: CreateUsingNew
- /// \param LifetimePolicy Lifetime policy, default: DefaultLifetime,
- /// \param ThreadingModel Threading policy,
- /// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
- ////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class CreationPolicy = CreateUsingNew,
- template <class> class LifetimePolicy = DefaultLifetime,
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
- class MutexPolicy = LOKI_DEFAULT_MUTEX
- >
- class SingletonHolder
- {
- public:
+////////////////////////////////////////////////////////////////////////////////
+/// \class SingletonHolder
+///
+/// \ingroup SingletonGroup
+///
+/// Provides Singleton amenities for a type T
+/// To protect that type from spurious instantiations,
+/// you have to protect it yourself.
+///
+/// \param CreationPolicy Creation policy, default: CreateUsingNew
+/// \param LifetimePolicy Lifetime policy, default: DefaultLifetime,
+/// \param ThreadingModel Threading policy,
+/// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
+////////////////////////////////////////////////////////////////////////////////
+template
+<
+typename T,
+ template <class> class CreationPolicy = CreateUsingNew,
+ template <class> class LifetimePolicy = DefaultLifetime,
+ template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
+ class MutexPolicy = LOKI_DEFAULT_MUTEX
+ >
+class SingletonHolder
+{
+public:
- /// Type of the singleton object
- typedef T ObjectType;
-
- /// Returns a reference to singleton object
- static T& Instance();
-
- private:
- // Helpers
- static void MakeInstance();
- static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton();
-
- // Protection
- SingletonHolder();
-
- // Data
- typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType;
- static PtrInstanceType pInstance_;
- static bool destroyed_;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder's data
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class C,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- typename SingletonHolder<T, C, L, M, X>::PtrInstanceType
- SingletonHolder<T, C, L, M, X>::pInstance_ = 0;
-
- template
- <
- class T,
- template <class> class C,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- bool SingletonHolder<T, C, L, M, X>::destroyed_ = false;
-
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder::Instance
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class LifetimePolicy,
- template <class, class> class ThreadingModel,
- class MutexPolicy
- >
- inline T& SingletonHolder<T, CreationPolicy,
- LifetimePolicy, ThreadingModel, MutexPolicy>::Instance()
+ /// Type of the singleton object
+ typedef T ObjectType;
+
+ /// Returns a reference to singleton object
+ static T& Instance();
+
+private:
+ // Helpers
+ static void MakeInstance();
+ static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton();
+
+ // Protection
+ SingletonHolder();
+
+ // Data
+ typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType;
+ static PtrInstanceType pInstance_;
+ static bool destroyed_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder's data
+////////////////////////////////////////////////////////////////////////////////
+
+template
+<
+class T,
+ template <class> class C,
+ template <class> class L,
+ template <class, class> class M,
+ class X
+ >
+typename SingletonHolder<T, C, L, M, X>::PtrInstanceType
+SingletonHolder<T, C, L, M, X>::pInstance_ = 0;
+
+template
+<
+class T,
+ template <class> class C,
+ template <class> class L,
+ template <class, class> class M,
+ class X
+ >
+bool SingletonHolder<T, C, L, M, X>::destroyed_ = false;
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder::Instance
+////////////////////////////////////////////////////////////////////////////////
+
+template
+<
+class T,
+ template <class> class CreationPolicy,
+ template <class> class LifetimePolicy,
+ template <class, class> class ThreadingModel,
+ class MutexPolicy
+ >
+inline T& SingletonHolder<T, CreationPolicy,
+ LifetimePolicy, ThreadingModel, MutexPolicy>::Instance()
+{
+ if (!pInstance_)
{
- if (!pInstance_)
- {
- MakeInstance();
- }
- return *pInstance_;
+ MakeInstance();
}
+ return *pInstance_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder::MakeInstance (helper for Instance)
+////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder::MakeInstance (helper for Instance)
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class LifetimePolicy,
- template <class, class> class ThreadingModel,
- class MutexPolicy
- >
- void SingletonHolder<T, CreationPolicy,
- LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance()
+template
+<
+class T,
+template <class> class CreationPolicy,
+template <class> class LifetimePolicy,
+template <class, class> class ThreadingModel,
+class MutexPolicy
+>
+void SingletonHolder<T, CreationPolicy,
+ LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance()
+{
+ typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard;
+ (void)guard;
+
+ if (!pInstance_)
{
- typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard;
- (void)guard;
-
- if (!pInstance_)
+ if (destroyed_)
{
- if (destroyed_)
- {
- destroyed_ = false;
- LifetimePolicy<T>::OnDeadReference();
- }
- pInstance_ = CreationPolicy<T>::Create();
- LifetimePolicy<T>::ScheduleDestruction(pInstance_,
- &DestroySingleton);
+ destroyed_ = false;
+ LifetimePolicy<T>::OnDeadReference();
}
+ pInstance_ = CreationPolicy<T>::Create();
+ LifetimePolicy<T>::ScheduleDestruction(pInstance_,
+ &DestroySingleton);
}
+}
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- void LOKI_C_CALLING_CONVENTION_QUALIFIER
- SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton()
- {
- assert(!destroyed_);
- CreationPolicy<T>::Destroy(pInstance_);
- pInstance_ = 0;
- destroyed_ = true;
- }
+template
+<
+class T,
+template <class> class CreationPolicy,
+template <class> class L,
+template <class, class> class M,
+class X
+>
+void LOKI_C_CALLING_CONVENTION_QUALIFIER
+SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton()
+{
+ assert(!destroyed_);
+ CreationPolicy<T>::Destroy(pInstance_);
+ pInstance_ = 0;
+ destroyed_ = true;
+}
- ////////////////////////////////////////////////////////////////////////////////
- /// \class Singleton
- ///
- /// \ingroup SingletonGroup
- ///
- /// Convenience template to implement a getter function for a singleton object.
- /// Often needed in a shared library which hosts singletons.
- ///
- /// \par Usage
- ///
- /// see test/SingletonDll
- ///
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/// \class Singleton
+///
+/// \ingroup SingletonGroup
+///
+/// Convenience template to implement a getter function for a singleton object.
+/// Often needed in a shared library which hosts singletons.
+///
+/// \par Usage
+///
+/// see test/SingletonDll
+///
+////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SINGLETON_EXPORT
#define LOKI_SINGLETON_EXPORT
#endif
- template<class T>
- class LOKI_SINGLETON_EXPORT Singleton
- {
- public:
- static T& Instance();
- };
+template<class T>
+class LOKI_SINGLETON_EXPORT Singleton
+{
+public:
+ static T& Instance();
+};
} // namespace Loki
bgstack15