Removed trailing whitespaces.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1085 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2011-06-21 03:29:50 +00:00
parent 2bc8950456
commit 6cb58ee8cc

View file

@ -2,14 +2,14 @@
// The Loki Library // The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu // Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book: // 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. // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any // Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright // purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this // notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation. // permission notice appear in supporting documentation.
// The author or Addison-Wesley Longman make no representations about the // The author or Addison-Wesley Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is" // suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SINGLETON_INC_ #ifndef LOKI_SINGLETON_INC_
@ -30,9 +30,9 @@
#include <memory> #include <memory>
#ifdef _MSC_VER #ifdef _MSC_VER
#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl #define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
#else #else
#define LOKI_C_CALLING_CONVENTION_QUALIFIER #define LOKI_C_CALLING_CONVENTION_QUALIFIER
#endif #endif
/// \defgroup SingletonGroup Singleton /// \defgroup SingletonGroup Singleton
@ -42,7 +42,7 @@
/// \ingroup SingletonGroup /// \ingroup SingletonGroup
/// The lifetimes of the singleton. /// The lifetimes of the singleton.
/// \par Special lifetime for SmallObjects /// \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 /// uses objects which are or inherit from Small(Value)Object
/// then you can't use the default lifetime: you must use the lifetime /// then you can't use the default lifetime: you must use the lifetime
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode /// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
@ -58,14 +58,14 @@ namespace Loki
{ {
#ifndef LOKI_MAKE_DLL #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 #else
void LOKI_EXPORT AtExitFn(); void LOKI_EXPORT AtExitFn();
#endif #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 #ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
// Helper data // Helper data
@ -87,23 +87,23 @@ namespace Loki
class LifetimeTracker class LifetimeTracker
{ {
public: public:
LifetimeTracker(unsigned int x) : longevity_(x) LifetimeTracker(unsigned int x) : longevity_(x)
{} {}
virtual ~LifetimeTracker() = 0; virtual ~LifetimeTracker() = 0;
static bool Compare(const LifetimeTracker* lhs, static bool Compare(const LifetimeTracker* lhs,
const LifetimeTracker* rhs) const LifetimeTracker* rhs)
{ {
return lhs->longevity_ > rhs->longevity_; return lhs->longevity_ > rhs->longevity_;
} }
private: private:
unsigned int longevity_; unsigned int longevity_;
}; };
// Definition required // Definition required
inline LifetimeTracker::~LifetimeTracker() {} inline LifetimeTracker::~LifetimeTracker() {}
// Helper destroyer function // Helper destroyer function
template <typename T> template <typename T>
@ -124,11 +124,13 @@ namespace Loki
, pTracked_(p) , pTracked_(p)
, destroyer_(d) , destroyer_(d)
{} {}
~ConcreteLifetimeTracker() ~ConcreteLifetimeTracker()
{ destroyer_(pTracked_); } { destroyer_(pTracked_); }
private: private:
/// Copy constructor is not implemented.
ConcreteLifetimeTracker( const ConcreteLifetimeTracker & );
T* pTracked_; T* pTracked_;
Destroyer destroyer_; Destroyer destroyer_;
}; };
@ -137,8 +139,8 @@ namespace Loki
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \ingroup LifetimeGroup /// \ingroup LifetimeGroup
/// ///
/// Assigns an object a longevity; ensures ordered destructions of objects /// Assigns an object a longevity; ensures ordered destructions of objects
/// registered thusly during the exit sequence of the application /// registered thusly during the exit sequence of the application
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -155,58 +157,58 @@ namespace Loki
pTrackerArray = new TrackerArray; pTrackerArray = new TrackerArray;
// automatically delete the ConcreteLifetimeTracker object when a exception is thrown // automatically delete the ConcreteLifetimeTracker object when a exception is thrown
std::auto_ptr<LifetimeTracker> std::auto_ptr<LifetimeTracker>
p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) ); p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) );
// Find correct position // Find correct position
TrackerArray::iterator pos = std::upper_bound( TrackerArray::iterator pos = std::upper_bound(
pTrackerArray->begin(), pTrackerArray->begin(),
pTrackerArray->end(), pTrackerArray->end(),
p.get(), p.get(),
LifetimeTracker::Compare); LifetimeTracker::Compare);
// Insert the pointer to the ConcreteLifetimeTracker object into the queue // Insert the pointer to the ConcreteLifetimeTracker object into the queue
pTrackerArray->insert(pos, p.get()); pTrackerArray->insert(pos, p.get());
// nothing has thrown: don't delete the ConcreteLifetimeTracker object // nothing has thrown: don't delete the ConcreteLifetimeTracker object
p.release(); p.release();
// Register a call to AtExitFn // Register a call to AtExitFn
std::atexit(Private::AtExitFn); std::atexit(Private::AtExitFn);
} }
#else #else
template <typename T, typename Destroyer> template <typename T, typename Destroyer>
void SetLongevity(T* pDynObject, unsigned int longevity, void SetLongevity(T* pDynObject, unsigned int longevity,
Destroyer d) Destroyer d)
{ {
using namespace Private; using namespace Private;
TrackerArray pNewArray = static_cast<TrackerArray>( TrackerArray pNewArray = static_cast<TrackerArray>(
std::realloc(pTrackerArray, std::realloc(pTrackerArray,
sizeof(*pTrackerArray) * (elements + 1))); sizeof(*pTrackerArray) * (elements + 1)));
if (!pNewArray) throw std::bad_alloc(); if (!pNewArray) throw std::bad_alloc();
// Delayed assignment for exception safety // Delayed assignment for exception safety
pTrackerArray = pNewArray; pTrackerArray = pNewArray;
LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>( LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
pDynObject, longevity, d); pDynObject, longevity, d);
// Insert a pointer to the object into the queue // Insert a pointer to the object into the queue
TrackerArray pos = std::upper_bound( TrackerArray pos = std::upper_bound(
pTrackerArray, pTrackerArray,
pTrackerArray + elements, pTrackerArray + elements,
p, p,
LifetimeTracker::Compare); LifetimeTracker::Compare);
std::copy_backward( std::copy_backward(
pos, pos,
pTrackerArray + elements, pTrackerArray + elements,
pTrackerArray + elements + 1); pTrackerArray + elements + 1);
*pos = p; *pos = p;
++elements; ++elements;
// Register a call to AtExitFn // Register a call to AtExitFn
std::atexit(Private::AtExitFn); std::atexit(Private::AtExitFn);
} }
@ -221,21 +223,21 @@ namespace Loki
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \struct CreateUsingNew /// \struct CreateUsingNew
/// ///
/// \ingroup CreationGroup /// \ingroup CreationGroup
/// Implementation of the CreationPolicy used by SingletonHolder /// Implementation of the CreationPolicy used by SingletonHolder
/// Creates objects using a straight call to the new operator /// Creates objects using a straight call to the new operator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <class T> struct CreateUsingNew template <class T> struct CreateUsingNew
{ {
static T* Create() static T* Create()
{ return new T; } { return new T; }
static void Destroy(T* p) static void Destroy(T* p)
{ delete p; } { delete p; }
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \struct CreateUsing /// \struct CreateUsing
/// ///
@ -265,13 +267,13 @@ namespace Loki
} }
}; };
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \struct CreateUsingMalloc /// \struct CreateUsingMalloc
/// ///
/// \ingroup CreationGroup /// \ingroup CreationGroup
/// Implementation of the CreationPolicy used by SingletonHolder /// Implementation of the CreationPolicy used by SingletonHolder
/// Creates objects using a call to std::malloc, followed by a call to the /// Creates objects using a call to std::malloc, followed by a call to the
/// placement new operator /// placement new operator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <class T> struct CreateUsingMalloc template <class T> struct CreateUsingMalloc
@ -282,14 +284,14 @@ namespace Loki
if (!p) return 0; if (!p) return 0;
return new(p) T; return new(p) T;
} }
static void Destroy(T* p) static void Destroy(T* p)
{ {
p->~T(); p->~T();
std::free(p); std::free(p);
} }
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \struct CreateStatic /// \struct CreateStatic
@ -297,15 +299,15 @@ namespace Loki
/// \ingroup CreationGroup /// \ingroup CreationGroup
/// Implementation of the CreationPolicy used by SingletonHolder /// Implementation of the CreationPolicy used by SingletonHolder
/// Creates an object in static memory /// Creates an object in static memory
/// Implementation is slightly nonportable because it uses the MaxAlign trick /// Implementation is slightly nonportable because it uses the MaxAlign trick
/// (an union of all types to ensure proper memory alignment). This trick is /// (an union of all types to ensure proper memory alignment). This trick is
/// nonportable in theory but highly portable in practice. /// nonportable in theory but highly portable in practice.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <class T> struct CreateStatic template <class T> struct CreateStatic
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4121 ) #pragma warning( disable : 4121 )
// alignment of a member was sensitive to packing // alignment of a member was sensitive to packing
#endif // _MSC_VER #endif // _MSC_VER
@ -323,17 +325,17 @@ namespace Loki
int Test::* pMember_; int Test::* pMember_;
int (Test::*pMemberFn_)(int); int (Test::*pMemberFn_)(int);
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning( pop ) #pragma warning( pop )
#endif // _MSC_VER #endif // _MSC_VER
static T* Create() static T* Create()
{ {
static MaxAlign staticMemory_; static MaxAlign staticMemory_;
return new(&staticMemory_) T; return new(&staticMemory_) T;
} }
static void Destroy(T* p) static void Destroy(T* p)
{ {
p->~T(); p->~T();
@ -353,7 +355,7 @@ namespace Loki
{ {
static void ScheduleDestruction(T*, atexit_pfn_t pFun) static void ScheduleDestruction(T*, atexit_pfn_t pFun)
{ std::atexit(pFun); } { std::atexit(pFun); }
static void OnDeadReference() static void OnDeadReference()
{ throw std::logic_error("Dead Reference Detected"); } { throw std::logic_error("Dead Reference Detected"); }
}; };
@ -363,7 +365,7 @@ namespace Loki
/// ///
/// \ingroup LifetimeGroup /// \ingroup LifetimeGroup
/// Implementation of the LifetimePolicy used by SingletonHolder /// Implementation of the LifetimePolicy used by SingletonHolder
/// Schedules an object's destruction as per C++ rules, and it allows object /// Schedules an object's destruction as per C++ rules, and it allows object
/// recreation by not throwing an exception from OnDeadReference /// recreation by not throwing an exception from OnDeadReference
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <class T> template <class T>
@ -377,20 +379,20 @@ namespace Loki
#endif #endif
std::atexit(pFun); std::atexit(pFun);
} }
static void OnDeadReference() static void OnDeadReference()
{ {
#ifndef ATEXIT_FIXED #ifndef ATEXIT_FIXED
destroyedOnce_ = true; destroyedOnce_ = true;
#endif #endif
} }
private: private:
#ifndef ATEXIT_FIXED #ifndef ATEXIT_FIXED
static bool destroyedOnce_; static bool destroyedOnce_;
#endif #endif
}; };
#ifndef ATEXIT_FIXED #ifndef ATEXIT_FIXED
template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false; template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
#endif #endif
@ -402,13 +404,13 @@ namespace Loki
/// ///
/// \ingroup LifetimeGroup /// \ingroup LifetimeGroup
/// ///
/// A DeletableSingleton allows the instantiated singleton to be /// A DeletableSingleton allows the instantiated singleton to be
/// destroyed at any time. The singleton can be reinstantiated at /// destroyed at any time. The singleton can be reinstantiated at
/// any time, even during program termination. /// any time, even during program termination.
/// If the singleton exists when the program terminates, it will /// If the singleton exists when the program terminates, it will
/// be automatically deleted. /// be automatically deleted.
/// ///
/// \par Usage: /// \par Usage:
/// The singleton can be deleted manually: /// The singleton can be deleted manually:
/// ///
/// DeletableSingleton<MyClass>::GracefulDelete(); /// DeletableSingleton<MyClass>::GracefulDelete();
@ -430,9 +432,9 @@ namespace Loki
needCallback = false; needCallback = false;
} }
} }
static void OnDeadReference() static void OnDeadReference()
{ {
} }
/// delete singleton object manually /// delete singleton object manually
static void GracefulDelete() static void GracefulDelete()
@ -442,12 +444,12 @@ namespace Loki
isDead = true; isDead = true;
deleter(); deleter();
} }
protected: protected:
static atexit_pfn_t deleter; static atexit_pfn_t deleter;
static bool isDead; static bool isDead;
static bool needCallback; static bool needCallback;
static void atexitCallback() static void atexitCallback()
{ {
#ifdef ATEXIT_FIXED #ifdef ATEXIT_FIXED
@ -458,13 +460,13 @@ namespace Loki
GracefulDelete(); GracefulDelete();
} }
}; };
template <class T> template <class T>
atexit_pfn_t DeletableSingleton<T>::deleter = 0; atexit_pfn_t DeletableSingleton<T>::deleter = 0;
template <class T> template <class T>
bool DeletableSingleton<T>::isDead = true; bool DeletableSingleton<T>::isDead = true;
template <class T> template <class T>
bool DeletableSingleton<T>::needCallback = true; bool DeletableSingleton<T>::needCallback = true;
@ -501,7 +503,7 @@ namespace Loki
Private::Adapter<T> adapter = { pFun }; Private::Adapter<T> adapter = { pFun };
SetLongevity(pObj, GetLongevity(pObj), adapter); SetLongevity(pObj, GetLongevity(pObj), adapter);
} }
static void OnDeadReference() static void OnDeadReference()
{ throw std::logic_error("Dead Reference Detected"); } { throw std::logic_error("Dead Reference Detected"); }
}; };
@ -518,11 +520,11 @@ namespace Loki
{ {
static void ScheduleDestruction(T*, atexit_pfn_t) static void ScheduleDestruction(T*, atexit_pfn_t)
{} {}
static void OnDeadReference() static void OnDeadReference()
{} {}
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \defgroup LongevityLifetimeGroup LongevityLifetime /// \defgroup LongevityLifetimeGroup LongevityLifetime
@ -537,7 +539,7 @@ namespace Loki
namespace LongevityLifetime namespace LongevityLifetime
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \struct SingletonFixedLongevity /// \struct SingletonFixedLongevity
/// ///
/// \ingroup LongevityLifetimeGroup /// \ingroup LongevityLifetimeGroup
/// Add your own lifetimes into the namespace 'LongevityLifetime' /// Add your own lifetimes into the namespace 'LongevityLifetime'
@ -551,13 +553,13 @@ namespace Loki
{ {
public: public:
virtual ~SingletonFixedLongevity() {} virtual ~SingletonFixedLongevity() {}
static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun) static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
{ {
Private::Adapter<T> adapter = { pFun }; Private::Adapter<T> adapter = { pFun };
SetLongevity(pObj, Longevity , adapter); SetLongevity(pObj, Longevity , adapter);
} }
static void OnDeadReference() static void OnDeadReference()
{ throw std::logic_error("Dead Reference Detected"); } { throw std::logic_error("Dead Reference Detected"); }
}; };
@ -578,11 +580,11 @@ namespace Loki
/// \struct DieFirst /// \struct DieFirst
/// \ingroup LongevityLifetimeGroup /// \ingroup LongevityLifetimeGroup
/// \brief Shortest possible SingletonWithLongevity lifetime: 0 /// \brief Shortest possible SingletonWithLongevity lifetime: 0
template <class T> template <class T>
struct DieFirst : SingletonFixedLongevity<0,T> struct DieFirst : SingletonFixedLongevity<0,T>
{}; {};
}//namespace LongevityLifetime }//namespace LongevityLifetime
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -590,12 +592,12 @@ namespace Loki
/// ///
/// \ingroup LifetimeGroup /// \ingroup LifetimeGroup
/// ///
/// Lifetime policyfor the SingletonHolder tempalte. /// Lifetime policyfor the SingletonHolder tempalte.
/// Followers will die after the master dies Followers will not die, if /// Followers will die after the master dies Followers will not die, if
/// - master never dies (NoDestroy policy) /// - master never dies (NoDestroy policy)
/// - master never created /// - master never created
/// - master dies not in the function registered with atexit /// - master dies not in the function registered with atexit
/// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete) /// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete)
/// ///
/// \par Usage: /// \par Usage:
/// ///
@ -611,7 +613,7 @@ namespace Loki
typedef std::vector<atexit_pfn_t> Container; typedef std::vector<atexit_pfn_t> Container;
typedef typename Container::iterator iterator; typedef typename Container::iterator iterator;
static Container* followers_; static Container* followers_;
public: public:
static void Init() static void Init()
{ {
@ -633,7 +635,7 @@ namespace Loki
{ {
Init(); Init();
for(iterator it = followers_->begin();it != followers_->end();++it) for(iterator it = followers_->begin();it != followers_->end();++it)
(*it)(); (*it)();
delete followers_; delete followers_;
} }
}; };
@ -641,7 +643,7 @@ namespace Loki
public: public:
/// \struct With /// \struct With
/// Template for the master /// Template for the master
/// \param Lifetime Lifetime policy for the master /// \param Lifetime Lifetime policy for the master
template<template <class> class Lifetime> template<template <class> class Lifetime>
struct With struct With
@ -656,7 +658,7 @@ namespace Loki
Followers<Master>::Init(); Followers<Master>::Init();
Lifetime<Master>::ScheduleDestruction(pObj, pFun); Lifetime<Master>::ScheduleDestruction(pObj, pFun);
// use same policy for the followers and force a new // use same policy for the followers and force a new
// template instantiation, this adds a additional atexit entry // template instantiation, this adds a additional atexit entry
// does not work with SetLonlevity, but there you can control // does not work with SetLonlevity, but there you can control
// the lifetime with the GetLongevity function. // the lifetime with the GetLongevity function.
@ -664,8 +666,8 @@ namespace Loki
} }
static void OnDeadReference() static void OnDeadReference()
{ {
throw std::logic_error("Dead Reference Detected"); throw std::logic_error("Dead Reference Detected");
} }
}; };
}; };
@ -677,7 +679,7 @@ namespace Loki
struct AfterMaster struct AfterMaster
{ {
/// \struct IsDestroyed /// \struct IsDestroyed
/// Policy for followers /// Policy for followers
template<class F> template<class F>
struct IsDestroyed struct IsDestroyed
{ {
@ -685,33 +687,33 @@ namespace Loki
{ {
Followers<Master>::AddFollower(pFun); Followers<Master>::AddFollower(pFun);
} }
static void OnDeadReference() static void OnDeadReference()
{ {
throw std::logic_error("Dead Reference Detected"); throw std::logic_error("Dead Reference Detected");
} }
}; };
}; };
}; };
template<class T> template<class T>
typename FollowIntoDeath::Followers<T>::Container* typename FollowIntoDeath::Followers<T>::Container*
FollowIntoDeath::Followers<T>::followers_ = 0; FollowIntoDeath::Followers<T>::followers_ = 0;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class SingletonHolder /// \class SingletonHolder
/// ///
/// \ingroup SingletonGroup /// \ingroup SingletonGroup
/// ///
/// Provides Singleton amenities for a type T /// Provides Singleton amenities for a type T
/// To protect that type from spurious instantiations, /// To protect that type from spurious instantiations,
/// you have to protect it yourself. /// you have to protect it yourself.
/// ///
/// \param CreationPolicy Creation policy, default: CreateUsingNew /// \param CreationPolicy Creation policy, default: CreateUsingNew
/// \param LifetimePolicy Lifetime policy, default: DefaultLifetime, /// \param LifetimePolicy Lifetime policy, default: DefaultLifetime,
/// \param ThreadingModel Threading policy, /// \param ThreadingModel Threading policy,
/// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL /// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template template
@ -731,21 +733,21 @@ namespace Loki
/// Returns a reference to singleton object /// Returns a reference to singleton object
static T& Instance(); static T& Instance();
private: private:
// Helpers // Helpers
static void MakeInstance(); static void MakeInstance();
static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton(); static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton();
// Protection // Protection
SingletonHolder(); SingletonHolder();
// Data // Data
typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType; typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType;
static PtrInstanceType pInstance_; static PtrInstanceType pInstance_;
static bool destroyed_; static bool destroyed_;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// SingletonHolder's data // SingletonHolder's data
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -783,7 +785,7 @@ namespace Loki
template <class, class> class ThreadingModel, template <class, class> class ThreadingModel,
class MutexPolicy class MutexPolicy
> >
inline T& SingletonHolder<T, CreationPolicy, inline T& SingletonHolder<T, CreationPolicy,
LifetimePolicy, ThreadingModel, MutexPolicy>::Instance() LifetimePolicy, ThreadingModel, MutexPolicy>::Instance()
{ {
if (!pInstance_) if (!pInstance_)
@ -805,12 +807,12 @@ namespace Loki
template <class, class> class ThreadingModel, template <class, class> class ThreadingModel,
class MutexPolicy class MutexPolicy
> >
void SingletonHolder<T, CreationPolicy, void SingletonHolder<T, CreationPolicy,
LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance() LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance()
{ {
typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard; typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard;
(void)guard; (void)guard;
if (!pInstance_) if (!pInstance_)
{ {
if (destroyed_) if (destroyed_)
@ -819,7 +821,7 @@ namespace Loki
destroyed_ = false; destroyed_ = false;
} }
pInstance_ = CreationPolicy<T>::Create(); pInstance_ = CreationPolicy<T>::Create();
LifetimePolicy<T>::ScheduleDestruction(pInstance_, LifetimePolicy<T>::ScheduleDestruction(pInstance_,
&DestroySingleton); &DestroySingleton);
} }
} }
@ -832,7 +834,7 @@ namespace Loki
template <class, class> class M, template <class, class> class M,
class X class X
> >
void LOKI_C_CALLING_CONVENTION_QUALIFIER void LOKI_C_CALLING_CONVENTION_QUALIFIER
SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton() SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton()
{ {
assert(!destroyed_); assert(!destroyed_);
@ -849,7 +851,7 @@ namespace Loki
/// ///
/// Convenience template to implement a getter function for a singleton object. /// Convenience template to implement a getter function for a singleton object.
/// Often needed in a shared library which hosts singletons. /// Often needed in a shared library which hosts singletons.
/// ///
/// \par Usage /// \par Usage
/// ///
/// see test/SingletonDll /// see test/SingletonDll