new impl for SetLongevity which looks more like c++ and circumvents the usage of the so called (ms) 'deprecated' function copy_backward
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@355 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
1c8bce4d43
commit
d45e0a1b08
2 changed files with 86 additions and 11 deletions
|
@ -23,6 +23,8 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
|
#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
|
||||||
|
@ -43,6 +45,24 @@ namespace Loki
|
||||||
|
|
||||||
namespace Private
|
namespace Private
|
||||||
{
|
{
|
||||||
|
void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
|
||||||
|
|
||||||
|
class LifetimeTracker;
|
||||||
|
|
||||||
|
#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 TrackerArray* pTrackerArray;
|
||||||
|
#else
|
||||||
|
// Helper data
|
||||||
|
typedef LifetimeTracker** TrackerArray;
|
||||||
|
extern TrackerArray pTrackerArray;
|
||||||
|
extern unsigned int elements;
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// class LifetimeTracker
|
// class LifetimeTracker
|
||||||
// Helper class for SetLongevity
|
// Helper class for SetLongevity
|
||||||
|
@ -68,11 +88,6 @@ namespace Loki
|
||||||
|
|
||||||
// Definition required
|
// Definition required
|
||||||
inline LifetimeTracker::~LifetimeTracker() {}
|
inline LifetimeTracker::~LifetimeTracker() {}
|
||||||
|
|
||||||
// Helper data
|
|
||||||
typedef LifetimeTracker** TrackerArray;
|
|
||||||
extern TrackerArray pTrackerArray;
|
|
||||||
extern unsigned int elements;
|
|
||||||
|
|
||||||
// Helper destroyer function
|
// Helper destroyer function
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -102,8 +117,6 @@ namespace Loki
|
||||||
Destroyer destroyer_;
|
Destroyer destroyer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
|
|
||||||
|
|
||||||
} // namespace Private
|
} // namespace Private
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -112,6 +125,38 @@ namespace Loki
|
||||||
/// 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
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
|
||||||
|
pDynObject, longevity, d);
|
||||||
|
|
||||||
|
// Find correct position
|
||||||
|
TrackerArray::iterator pos = std::upper_bound(
|
||||||
|
pTrackerArray->begin(),
|
||||||
|
pTrackerArray->end(),
|
||||||
|
p,
|
||||||
|
LifetimeTracker::Compare);
|
||||||
|
|
||||||
|
// Insert a pointer to the object into the queue
|
||||||
|
pTrackerArray->insert(pos, p);
|
||||||
|
|
||||||
|
// Register a call to AtExitFn
|
||||||
|
std::atexit(Private::AtExitFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
@ -128,7 +173,7 @@ namespace Loki
|
||||||
|
|
||||||
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,
|
||||||
|
@ -146,6 +191,8 @@ namespace Loki
|
||||||
std::atexit(Private::AtExitFn);
|
std::atexit(Private::AtExitFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetLongevity(T* pDynObject, unsigned int longevity,
|
void SetLongevity(T* pDynObject, unsigned int longevity,
|
||||||
typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
|
typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
|
||||||
|
|
|
@ -13,20 +13,46 @@
|
||||||
// without express or implied warranty.
|
// without express or implied warranty.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Last update: June 20, 2001
|
|
||||||
|
|
||||||
#include "../include/loki/Singleton.h"
|
#include "../include/loki/Singleton.h"
|
||||||
|
|
||||||
using namespace Loki::Private;
|
|
||||||
|
|
||||||
|
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
|
||||||
|
Loki::Private::TrackerArray* Loki::Private::pTrackerArray = 0;
|
||||||
|
#else
|
||||||
Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0;
|
Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0;
|
||||||
unsigned int Loki::Private::elements = 0;
|
unsigned int Loki::Private::elements = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// function AtExitFn
|
// function AtExitFn
|
||||||
// Ensures proper destruction of objects with longevity
|
// Ensures proper destruction of objects with longevity
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
|
||||||
|
|
||||||
|
void LOKI_C_CALLING_CONVENTION_QUALIFIER Loki::Private::AtExitFn()
|
||||||
|
{
|
||||||
|
assert(pTrackerArray!=0 && !pTrackerArray->empty());
|
||||||
|
|
||||||
|
// Pick the element at the top of the stack
|
||||||
|
LifetimeTracker* pTop = pTrackerArray->back();
|
||||||
|
|
||||||
|
// Remove that object off the stack _before_ deleting pTop
|
||||||
|
pTrackerArray->pop_back();
|
||||||
|
|
||||||
|
// Destroy the element
|
||||||
|
delete pTop;
|
||||||
|
|
||||||
|
// Destroy stack when it's empty _after_ deleting pTop
|
||||||
|
if(pTrackerArray->empty())
|
||||||
|
{
|
||||||
|
delete pTrackerArray;
|
||||||
|
pTrackerArray = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
void LOKI_C_CALLING_CONVENTION_QUALIFIER Loki::Private::AtExitFn()
|
void LOKI_C_CALLING_CONVENTION_QUALIFIER Loki::Private::AtExitFn()
|
||||||
{
|
{
|
||||||
assert(elements > 0 && pTrackerArray != 0);
|
assert(elements > 0 && pTrackerArray != 0);
|
||||||
|
@ -41,6 +67,8 @@ void LOKI_C_CALLING_CONVENTION_QUALIFIER Loki::Private::AtExitFn()
|
||||||
delete pTop;
|
delete pTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Change log:
|
// Change log:
|
||||||
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue