2005-10-14 18:48:10 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// The Loki Library
|
|
|
|
|
// Copyright (c) 2005 Richard Sposato
|
2005-11-02 13:58:18 +00:00
|
|
|
|
// Copyright (c) 2005 Peter K<>mmel
|
2005-10-14 18:48:10 +00:00
|
|
|
|
// 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 authors make no representations about the
|
|
|
|
|
// suitability of this software for any purpose. It is provided "as is"
|
|
|
|
|
// without express or implied warranty.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2006-10-17 20:36:13 +00:00
|
|
|
|
// $Id$
|
2005-10-14 18:48:10 +00:00
|
|
|
|
|
|
|
|
|
|
2006-01-05 09:55:09 +00:00
|
|
|
|
#include <loki/SmallObj.h>
|
|
|
|
|
#include <loki/Singleton.h>
|
2005-10-14 18:48:10 +00:00
|
|
|
|
#include <iostream>
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
// define DO_EXTRA_LOKI_TESTS in src/SmallObj.cpp to get
|
|
|
|
|
// a message when a SmallObject is created/deleted.
|
2005-10-14 18:48:10 +00:00
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
2005-11-07 12:06:43 +00:00
|
|
|
|
// LongevityLifetime Parent/Child policies
|
2005-11-02 13:58:18 +00:00
|
|
|
|
//
|
2005-10-14 18:48:10 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
2005-12-08 21:03:02 +00:00
|
|
|
|
512, 32, 4, Loki::LongevityLifetime::DieAsSmallObjectParent
|
2005-11-02 13:58:18 +00:00
|
|
|
|
>
|
2005-11-07 12:06:43 +00:00
|
|
|
|
SmallObjectParent;
|
2005-11-02 14:15:44 +00:00
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
class SmallObjectChild : public SmallObjectParent
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
typedef Loki::SingletonHolder< SmallObjectChild, Loki::CreateUsingNew,
|
2005-11-13 13:39:15 +00:00
|
|
|
|
Loki::LongevityLifetime::DieAsSmallObjectChild>
|
2005-10-14 18:48:10 +00:00
|
|
|
|
MySmallSingleton;
|
|
|
|
|
|
|
|
|
|
/// Returns reference to the singleton.
|
2005-11-07 12:06:43 +00:00
|
|
|
|
inline static SmallObjectChild & Instance( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
return MySmallSingleton::Instance();
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
SmallObjectChild( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "SmallObjectChild created" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
2005-11-07 12:06:43 +00:00
|
|
|
|
~SmallObjectChild( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "~SmallObjectChild" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
void DoThat( void )
|
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "SmallObjectChild::DoThat" << endl << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
char m_stuff[ 16 ];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
2005-11-07 12:06:43 +00:00
|
|
|
|
// SingletonWithLongevity policy
|
2005-11-02 13:58:18 +00:00
|
|
|
|
//
|
2005-10-14 18:48:10 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
|
|
|
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
|
|
|
|
LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
2005-11-07 12:06:43 +00:00
|
|
|
|
Loki::SingletonWithLongevity
|
2005-11-02 13:58:18 +00:00
|
|
|
|
>
|
2005-11-07 12:06:43 +00:00
|
|
|
|
LongLivedObject;
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
class LongLivedSingleton : public LongLivedObject
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
typedef Loki::SingletonHolder< LongLivedSingleton, Loki::CreateUsingNew,
|
2005-11-13 13:39:15 +00:00
|
|
|
|
Loki::SingletonWithLongevity>
|
2005-10-14 18:48:10 +00:00
|
|
|
|
MySmallSingleton;
|
|
|
|
|
|
|
|
|
|
/// Returns reference to the singleton.
|
2005-11-07 12:06:43 +00:00
|
|
|
|
inline static LongLivedSingleton & Instance( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
return MySmallSingleton::Instance();
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
LongLivedSingleton( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "LongLivedSingleton created" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
2005-11-07 12:06:43 +00:00
|
|
|
|
~LongLivedSingleton( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "~LongLivedSingleton" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
void DoThat( void )
|
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "LongLivedSingleton::DoThat" << endl << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
char m_stuff[ 16 ];
|
|
|
|
|
};
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
inline unsigned int GetLongevity( LongLivedSingleton * )
|
|
|
|
|
{
|
|
|
|
|
/// @note Must return a longevity level lower than the one in SmallObj.h.
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !defined(_MSC_VER) || (_MSC_VER>=1400)
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
2005-11-07 12:06:43 +00:00
|
|
|
|
// FollowIntoDeath policy
|
2005-11-02 13:58:18 +00:00
|
|
|
|
//
|
2005-10-14 18:48:10 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
|
|
|
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
|
|
|
|
LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
2005-11-07 12:06:43 +00:00
|
|
|
|
Loki::FollowIntoDeath::With<Loki::DefaultLifetime>::AsMasterLifetime
|
2005-11-02 13:58:18 +00:00
|
|
|
|
>
|
2005-11-07 12:06:43 +00:00
|
|
|
|
MasterObject;
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
|
|
|
|
|
class FollowerSingleton : public MasterObject
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
typedef Loki::SingletonHolder< FollowerSingleton, Loki::CreateUsingNew,
|
2005-11-13 13:39:15 +00:00
|
|
|
|
Loki::FollowIntoDeath::AfterMaster<FollowerSingleton::ObjAllocatorSingleton>::IsDestroyed>
|
2005-10-14 18:48:10 +00:00
|
|
|
|
MySmallSingleton;
|
|
|
|
|
|
|
|
|
|
/// Returns reference to the singleton.
|
2005-11-07 12:06:43 +00:00
|
|
|
|
inline static FollowerSingleton & Instance( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
|
|
|
|
return MySmallSingleton::Instance();
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
FollowerSingleton( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "FollowerSingleton created" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
2005-11-07 12:06:43 +00:00
|
|
|
|
~FollowerSingleton( void )
|
2005-10-14 18:48:10 +00:00
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "~FollowerSingleton" << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
void DoThat( void )
|
|
|
|
|
{
|
2005-11-07 12:06:43 +00:00
|
|
|
|
cout << "FollowerSingleton::DoThat" << endl << endl;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
char m_stuff[ 16 ];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
#endif
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-11-13 13:39:15 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// NoDestroy policy
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
|
|
|
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
|
|
|
|
LOKI_DEFAULT_OBJECT_ALIGNMENT, Loki::NoDestroy >
|
|
|
|
|
ImmortalObject;
|
|
|
|
|
|
|
|
|
|
class ImmortalSingleton : public ImmortalObject
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
typedef Loki::SingletonHolder< ImmortalSingleton, Loki::CreateUsingNew,
|
|
|
|
|
Loki::NoDestroy>
|
|
|
|
|
MySmallSingleton;
|
|
|
|
|
|
|
|
|
|
/// Returns reference to the singleton.
|
|
|
|
|
inline static ImmortalSingleton & Instance( void )
|
|
|
|
|
{
|
|
|
|
|
return MySmallSingleton::Instance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImmortalSingleton( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "ImmortalSingleton created" << endl;
|
|
|
|
|
}
|
|
|
|
|
~ImmortalSingleton( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "~ImmortalSingleton destructor should never get called!" << endl;
|
|
|
|
|
}
|
|
|
|
|
void DoThat( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "ImmortalSingleton::DoThat" << endl << endl;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
char m_stuff[ 16 ];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// NoDestroy and SingletonWithLongevity policy combination
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
class MortalSingleton : public ImmortalObject
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
typedef Loki::SingletonHolder< MortalSingleton, Loki::CreateUsingNew,
|
|
|
|
|
Loki::SingletonWithLongevity>
|
|
|
|
|
MySmallSingleton;
|
|
|
|
|
|
|
|
|
|
/// Returns reference to the singleton.
|
|
|
|
|
inline static MortalSingleton & Instance( void )
|
|
|
|
|
{
|
|
|
|
|
return MySmallSingleton::Instance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MortalSingleton( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "MortalSingleton created" << endl;
|
|
|
|
|
}
|
|
|
|
|
~MortalSingleton( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "~MortalSingleton" << endl;
|
|
|
|
|
}
|
|
|
|
|
void DoThat( void )
|
|
|
|
|
{
|
|
|
|
|
cout << "MortalSingleton::DoThat" << endl << endl;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
char m_stuff[ 16 ];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline unsigned int GetLongevity( MortalSingleton * )
|
|
|
|
|
{
|
|
|
|
|
/// @note Must return a longevity level lower than the one in SmallObj.h.
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// detect memory leaks on MSVC Ide
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
2005-11-13 13:39:15 +00:00
|
|
|
|
//#define LOKI_MSVC_CHECK_FOR_MEMORY_LEAKS
|
|
|
|
|
#ifdef LOKI_MSVC_CHECK_FOR_MEMORY_LEAKS
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
|
|
|
|
#include <crtdbg.h>
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
|
|
void heap_debug()
|
|
|
|
|
{
|
|
|
|
|
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
|
|
|
|
|
|
|
|
|
// Turn on leak-checking bit
|
|
|
|
|
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
|
|
|
|
|
|
|
|
|
|
//tmpFlag |= _CRTDBG_CHECK_MasterLWMasterYS_DF;
|
|
|
|
|
|
|
|
|
|
// Turn off CRT block checking bit
|
|
|
|
|
tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;
|
|
|
|
|
|
|
|
|
|
// Set flag to the new value
|
|
|
|
|
_CrtSetDbgFlag( tmpFlag );
|
|
|
|
|
}
|
2005-11-13 13:39:15 +00:00
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
void heap_debug()
|
|
|
|
|
{}
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// main
|
|
|
|
|
//
|
2005-10-14 18:48:10 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
2005-11-02 13:58:18 +00:00
|
|
|
|
heap_debug();
|
|
|
|
|
|
|
|
|
|
cout << endl
|
2005-11-13 13:39:15 +00:00
|
|
|
|
<< "This program tests the lifetime policies for Loki's " << endl
|
2005-11-02 13:58:18 +00:00
|
|
|
|
<< "Small-Object Allocator and singleton objects that are derived " << endl
|
|
|
|
|
<< "from SmallObject or SmallValueObject." << endl
|
|
|
|
|
<< endl
|
|
|
|
|
<< "Use one of the following lifetime policies" << endl
|
|
|
|
|
<< "to manage the lifetime dependency:" << endl
|
|
|
|
|
<< endl
|
2005-11-13 13:39:15 +00:00
|
|
|
|
<< "- LongevityLifetime Parent/Child: SmallObject has" << endl
|
|
|
|
|
<< " LongevityLifetime::DieAsSmallObjectParent" << endl
|
|
|
|
|
<< " policy and the derived Singleton has " << endl
|
2005-11-07 12:06:43 +00:00
|
|
|
|
<< " LongevityLifetime::DieAsSmallObjectChild" << endl
|
|
|
|
|
<< " This is tested by the SmallObjectChild class." << endl
|
2005-11-02 13:58:18 +00:00
|
|
|
|
<< endl
|
2005-11-13 13:39:15 +00:00
|
|
|
|
<< "- Both SmallObject and derived Singleton use" << endl
|
|
|
|
|
<< " SingletonWithLongevity" << endl
|
|
|
|
|
<< " policy. This is tested by the LongLivedSingleton class." << endl
|
2005-11-07 12:06:43 +00:00
|
|
|
|
<< endl
|
|
|
|
|
#if !defined(_MSC_VER) || (_MSC_VER>=1400)
|
2005-11-13 13:39:15 +00:00
|
|
|
|
<< "- FollowIntoDeath: SmallObject has" << endl
|
|
|
|
|
<< " FollowIntoDeath::With<LIFETIME>::AsMasterLiftime" << endl
|
|
|
|
|
<< " policy and the derived Singleton has " << endl
|
|
|
|
|
<< " FollowIntoDeath::AfterMaster<MASTERSINGLETON>::IsDestroyed" << endl
|
|
|
|
|
<< " policy. This is tested by the FollowerSingleton class." << endl
|
2005-11-02 13:58:18 +00:00
|
|
|
|
<< endl
|
2005-11-07 12:06:43 +00:00
|
|
|
|
#endif
|
2005-11-13 13:39:15 +00:00
|
|
|
|
<< "- Both SmallObject and derived Singleton use" << endl
|
|
|
|
|
<< " NoDestroy" << endl
|
|
|
|
|
<< " policy. This is tested by the ImmortalSingleton class." << endl
|
|
|
|
|
<< " Note: yow will get memory leaks" << endl
|
|
|
|
|
<< endl
|
|
|
|
|
<< "- SmallObject has"<< endl
|
|
|
|
|
<< " NoDestroy" << endl
|
|
|
|
|
<< " policy but the derived Singleton has" << endl
|
|
|
|
|
<< " SingletonWithLongevity" << endl
|
|
|
|
|
<< " policy. This is tested by the MortalSingleton class." << endl
|
|
|
|
|
<< " Note: yow will get memory leaks" << endl << endl
|
|
|
|
|
|
2005-11-02 13:58:18 +00:00
|
|
|
|
<< endl << endl
|
|
|
|
|
<< "If this program executes without crashing or asserting" << endl
|
2005-11-07 12:06:43 +00:00
|
|
|
|
<< "at exit time, then all policies work." << endl << endl;
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-11-07 12:06:43 +00:00
|
|
|
|
|
|
|
|
|
SmallObjectChild::Instance().DoThat();
|
2005-10-14 18:48:10 +00:00
|
|
|
|
LongLivedSingleton::Instance().DoThat();
|
2005-11-07 12:06:43 +00:00
|
|
|
|
|
|
|
|
|
#if !defined(_MSC_VER) || (_MSC_VER>=1400)
|
|
|
|
|
FollowerSingleton::Instance().DoThat();
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-11-13 13:39:15 +00:00
|
|
|
|
#define ENABLE_MEMORY_LEAK
|
|
|
|
|
#ifdef ENABLE_MEMORY_LEAK
|
|
|
|
|
ImmortalSingleton::Instance().DoThat();
|
|
|
|
|
MortalSingleton::Instance().DoThat();
|
|
|
|
|
#else
|
|
|
|
|
cout << endl;
|
|
|
|
|
cout << "ImmortalSingleton and MortalSingleton" << endl;
|
|
|
|
|
cout << "are disabled due to the test on memory leaks.";
|
|
|
|
|
cout << endl << endl;
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-01-04 23:54:30 +00:00
|
|
|
|
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
|
|
|
|
system("PAUSE");
|
2005-11-07 12:06:43 +00:00
|
|
|
|
#endif
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-11-13 13:39:15 +00:00
|
|
|
|
cout << endl<< endl << "now leaving main" << endl;
|
|
|
|
|
cout << "________________________________" << endl << endl;
|
2005-11-02 13:58:18 +00:00
|
|
|
|
|
2005-10-30 14:03:23 +00:00
|
|
|
|
return 0;
|
2005-10-14 18:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|