diff --git a/include/loki/Singleton.h b/include/loki/Singleton.h index 195da98..ed7b44d 100644 --- a/include/loki/Singleton.h +++ b/include/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 #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 @@ -58,14 +58,14 @@ namespace Loki { #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(); #endif 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 @@ -87,23 +87,23 @@ namespace Loki class LifetimeTracker { public: - LifetimeTracker(unsigned int x) : longevity_(x) + 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() {} + inline LifetimeTracker::~LifetimeTracker() {} // Helper destroyer function template @@ -124,11 +124,13 @@ namespace Loki , pTracked_(p) , destroyer_(d) {} - + ~ConcreteLifetimeTracker() { destroyer_(pTracked_); } - + private: + /// Copy constructor is not implemented. + ConcreteLifetimeTracker( const ConcreteLifetimeTracker & ); T* pTracked_; Destroyer destroyer_; }; @@ -137,8 +139,8 @@ namespace Loki //////////////////////////////////////////////////////////////////////////////// /// \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 //////////////////////////////////////////////////////////////////////////////// @@ -155,58 +157,58 @@ namespace Loki pTrackerArray = new TrackerArray; // automatically delete the ConcreteLifetimeTracker object when a exception is thrown - std::auto_ptr + std::auto_ptr p( new ConcreteLifetimeTracker(pDynObject, longevity, d) ); // Find correct position TrackerArray::iterator pos = std::upper_bound( - pTrackerArray->begin(), - pTrackerArray->end(), - p.get(), + 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 void SetLongevity(T* pDynObject, unsigned int longevity, Destroyer d) { using namespace Private; - + TrackerArray pNewArray = static_cast( - std::realloc(pTrackerArray, + std::realloc(pTrackerArray, sizeof(*pTrackerArray) * (elements + 1))); if (!pNewArray) throw std::bad_alloc(); - + // Delayed assignment for exception safety pTrackerArray = pNewArray; - + LifetimeTracker* p = new ConcreteLifetimeTracker( pDynObject, longevity, d); - + // Insert a pointer to the object into the queue TrackerArray pos = std::upper_bound( - pTrackerArray, - pTrackerArray + elements, - p, + pTrackerArray, + pTrackerArray + elements, + p, LifetimeTracker::Compare); std::copy_backward( - pos, + pos, pTrackerArray + elements, pTrackerArray + elements + 1); *pos = p; ++elements; - + // Register a call to AtExitFn std::atexit(Private::AtExitFn); } @@ -221,21 +223,21 @@ namespace Loki } //////////////////////////////////////////////////////////////////////////////// - /// \struct CreateUsingNew + /// \struct CreateUsingNew /// /// \ingroup CreationGroup /// 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 struct CreateUsingNew { static T* Create() { return new T; } - + static void Destroy(T* p) { delete p; } }; - + //////////////////////////////////////////////////////////////////////////////// /// \struct CreateUsing /// @@ -265,13 +267,13 @@ namespace Loki } }; }; - + //////////////////////////////////////////////////////////////////////////////// /// \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 + /// Creates objects using a call to std::malloc, followed by a call to the /// placement new operator //////////////////////////////////////////////////////////////////////////////// template struct CreateUsingMalloc @@ -282,14 +284,14 @@ namespace Loki if (!p) return 0; return new(p) T; } - + static void Destroy(T* p) { p->~T(); std::free(p); } }; - + //////////////////////////////////////////////////////////////////////////////// /// \struct CreateStatic @@ -297,15 +299,15 @@ namespace Loki /// \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 + /// 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 struct CreateStatic { - + #ifdef _MSC_VER -#pragma warning( push ) +#pragma warning( push ) #pragma warning( disable : 4121 ) // alignment of a member was sensitive to packing #endif // _MSC_VER @@ -323,17 +325,17 @@ namespace Loki 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(); @@ -353,7 +355,7 @@ namespace Loki { static void ScheduleDestruction(T*, atexit_pfn_t pFun) { std::atexit(pFun); } - + static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); } }; @@ -363,7 +365,7 @@ namespace Loki /// /// \ingroup LifetimeGroup /// 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 //////////////////////////////////////////////////////////////////////////////// template @@ -377,20 +379,20 @@ namespace Loki #endif std::atexit(pFun); } - + static void OnDeadReference() { #ifndef ATEXIT_FIXED destroyedOnce_ = true; #endif } - + private: #ifndef ATEXIT_FIXED static bool destroyedOnce_; #endif }; - + #ifndef ATEXIT_FIXED template bool PhoenixSingleton::destroyedOnce_ = false; #endif @@ -402,13 +404,13 @@ namespace Loki /// /// \ingroup LifetimeGroup /// - /// A DeletableSingleton allows the instantiated singleton to be - /// destroyed at any time. The singleton can be reinstantiated at + /// 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 + /// If the singleton exists when the program terminates, it will /// be automatically deleted. /// - /// \par Usage: + /// \par Usage: /// The singleton can be deleted manually: /// /// DeletableSingleton::GracefulDelete(); @@ -430,9 +432,9 @@ namespace Loki needCallback = false; } } - + static void OnDeadReference() - { + { } /// delete singleton object manually static void GracefulDelete() @@ -442,12 +444,12 @@ namespace Loki isDead = true; deleter(); } - + protected: static atexit_pfn_t deleter; static bool isDead; static bool needCallback; - + static void atexitCallback() { #ifdef ATEXIT_FIXED @@ -458,13 +460,13 @@ namespace Loki GracefulDelete(); } }; - + template atexit_pfn_t DeletableSingleton::deleter = 0; - + template bool DeletableSingleton::isDead = true; - + template bool DeletableSingleton::needCallback = true; @@ -501,7 +503,7 @@ namespace Loki Private::Adapter adapter = { pFun }; SetLongevity(pObj, GetLongevity(pObj), adapter); } - + static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); } }; @@ -518,11 +520,11 @@ namespace Loki { static void ScheduleDestruction(T*, atexit_pfn_t) {} - + static void OnDeadReference() {} }; - + //////////////////////////////////////////////////////////////////////////////// /// \defgroup LongevityLifetimeGroup LongevityLifetime @@ -537,7 +539,7 @@ namespace Loki namespace LongevityLifetime { //////////////////////////////////////////////////////////////////////////////// - /// \struct SingletonFixedLongevity + /// \struct SingletonFixedLongevity /// /// \ingroup LongevityLifetimeGroup /// Add your own lifetimes into the namespace 'LongevityLifetime' @@ -551,13 +553,13 @@ namespace Loki { public: virtual ~SingletonFixedLongevity() {} - + static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun) { Private::Adapter adapter = { pFun }; SetLongevity(pObj, Longevity , adapter); } - + static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); } }; @@ -578,11 +580,11 @@ namespace Loki /// \struct DieFirst /// \ingroup LongevityLifetimeGroup - /// \brief Shortest possible SingletonWithLongevity lifetime: 0 + /// \brief Shortest possible SingletonWithLongevity lifetime: 0 template struct DieFirst : SingletonFixedLongevity<0,T> {}; - + }//namespace LongevityLifetime //////////////////////////////////////////////////////////////////////////////// @@ -590,12 +592,12 @@ namespace Loki /// /// \ingroup LifetimeGroup /// - /// Lifetime policyfor the SingletonHolder tempalte. + /// 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) + /// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete) /// /// \par Usage: /// @@ -611,7 +613,7 @@ namespace Loki typedef std::vector Container; typedef typename Container::iterator iterator; static Container* followers_; - + public: static void Init() { @@ -633,7 +635,7 @@ namespace Loki { Init(); for(iterator it = followers_->begin();it != followers_->end();++it) - (*it)(); + (*it)(); delete followers_; } }; @@ -641,7 +643,7 @@ namespace Loki public: /// \struct With - /// Template for the master + /// Template for the master /// \param Lifetime Lifetime policy for the master template