2005-07-28 14:27:12 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// The Loki Library
|
|
|
|
// Copyright (c) 2005 by Peter Kuemmel
|
|
|
|
//
|
|
|
|
// Code covered by the MIT License
|
|
|
|
// 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-07-28 14:27:12 +00:00
|
|
|
|
|
|
|
//#define CLASS_LEVEL_THERADING
|
|
|
|
|
2005-10-06 17:50:51 +00:00
|
|
|
#define USE_SEQUENCE
|
|
|
|
|
2005-07-28 14:27:12 +00:00
|
|
|
#include <iostream>
|
2005-11-12 16:52:36 +00:00
|
|
|
#include <string>
|
2006-01-05 00:23:44 +00:00
|
|
|
#include <loki/Factory.h>
|
|
|
|
#include <loki/Functor.h>
|
2005-10-30 13:49:44 +00:00
|
|
|
|
|
|
|
#ifdef LOKI_DISABLE_TYPELIST_MACROS
|
|
|
|
#define USE_WQUENCE
|
|
|
|
#endif
|
|
|
|
|
2005-10-06 17:50:51 +00:00
|
|
|
#ifdef USE_SEQUENCE
|
2006-01-05 00:23:44 +00:00
|
|
|
#include <loki/Sequence.h>
|
2005-11-01 11:38:19 +00:00
|
|
|
|
2005-10-06 17:50:51 +00:00
|
|
|
#endif
|
2005-07-28 14:27:12 +00:00
|
|
|
|
2005-11-01 11:38:19 +00:00
|
|
|
using namespace Loki;
|
2005-07-28 14:27:12 +00:00
|
|
|
using std::cout;
|
|
|
|
using std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
|
// Object to create: Product
|
|
|
|
// Constructor with 0 and 2 arguments
|
|
|
|
////////////////////////////////////////////
|
|
|
|
|
|
|
|
class AbstractProduct{};
|
|
|
|
|
|
|
|
class Product : public AbstractProduct
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Product(){}
|
|
|
|
Product( int, int ){}
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Factory for creation a Product object without parameters
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
typedef SingletonHolder
|
|
|
|
<
|
2005-11-01 11:38:19 +00:00
|
|
|
Factory< AbstractProduct, int >,
|
2005-11-07 12:06:43 +00:00
|
|
|
CreateUsingNew,
|
|
|
|
Loki::LongevityLifetime::DieAsSmallObjectChild
|
2005-07-28 14:27:12 +00:00
|
|
|
>
|
|
|
|
PFactoryNull;
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
// Factory for creation a Product object with 2 parameters
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
typedef SingletonHolder
|
|
|
|
<
|
2005-10-06 17:50:51 +00:00
|
|
|
#ifndef USE_SEQUENCE
|
2005-11-12 16:52:36 +00:00
|
|
|
Factory< AbstractProduct, std::string, LOKI_TYPELIST_2( int, int ) >,
|
2005-10-06 17:50:51 +00:00
|
|
|
#else
|
2005-11-12 16:52:36 +00:00
|
|
|
Factory< AbstractProduct, std::string, Seq< int, int > >,
|
2005-10-06 17:50:51 +00:00
|
|
|
#endif
|
2005-11-07 12:06:43 +00:00
|
|
|
CreateUsingNew,
|
|
|
|
Loki::LongevityLifetime::DieAsSmallObjectChild
|
2005-07-28 14:27:12 +00:00
|
|
|
>
|
|
|
|
PFactory;
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
// Creator functions with different names
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
Product* createProductNull()
|
|
|
|
{
|
|
|
|
cout << "createProductNull()" << endl;
|
|
|
|
return new Product;
|
|
|
|
}
|
|
|
|
Product* createProductParm( int a, int b )
|
|
|
|
{
|
|
|
|
cout << "createProductParm( int a, int b ) " << endl;
|
|
|
|
return new Product( a, b );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
// Overloaded creator functions
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
Product* createProductOver()
|
|
|
|
{
|
|
|
|
cout << "createProductOver()" << endl;
|
|
|
|
return new Product;
|
|
|
|
}
|
|
|
|
Product* createProductOver( int a, int b )
|
|
|
|
{
|
|
|
|
cout << "createProductOver( int a, int b )" << endl;
|
|
|
|
return new Product( a, b );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
// Creator functions are polymorphic member functions
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class AbstractCreator{
|
|
|
|
public:
|
2006-01-04 23:45:08 +00:00
|
|
|
virtual ~AbstractCreator() {}
|
2005-07-28 14:27:12 +00:00
|
|
|
virtual AbstractProduct* create() = 0;
|
|
|
|
virtual AbstractProduct* createParm( int, int ) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Creator : public AbstractCreator{
|
|
|
|
public:
|
|
|
|
Creator(){};
|
|
|
|
AbstractProduct* create()
|
|
|
|
{
|
|
|
|
cout << "Creator::create()" << endl;
|
|
|
|
return new Product;
|
|
|
|
}
|
|
|
|
AbstractProduct* createParm( int a, int b )
|
|
|
|
{
|
|
|
|
cout << "Creator::create( int a, int b )" << endl;
|
|
|
|
return new Product( a,b );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
// Creator functions are member functions of a template class
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
template< class T>
|
|
|
|
class CreatorT{
|
|
|
|
public:
|
|
|
|
CreatorT(){};
|
|
|
|
T* create()
|
|
|
|
{
|
|
|
|
cout << "CreatorT<T>::create()" << endl;
|
|
|
|
return new T;
|
|
|
|
}
|
|
|
|
T* createParm( int a, int b )
|
|
|
|
{
|
|
|
|
cout << "CreatorT<T>::create( int a, int b )" << endl;
|
|
|
|
return new T( a,b );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
// get creator functions on runntime
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
2005-10-06 17:50:51 +00:00
|
|
|
#ifndef USE_SEQUENCE
|
2005-09-26 07:33:05 +00:00
|
|
|
typedef Functor<Product*,LOKI_TYPELIST_2(int,int)> CreateFunctor;
|
2005-10-06 17:50:51 +00:00
|
|
|
#else
|
2005-10-30 13:49:44 +00:00
|
|
|
typedef Functor<Product*,Seq<int,int> > CreateFunctor;
|
2005-10-06 17:50:51 +00:00
|
|
|
#endif
|
2005-07-28 14:27:12 +00:00
|
|
|
|
|
|
|
typedef
|
|
|
|
SingletonHolder
|
|
|
|
<
|
2005-10-06 17:50:51 +00:00
|
|
|
#ifndef USE_SEQUENCE
|
2005-11-01 11:38:19 +00:00
|
|
|
Factory< AbstractProduct, int,LOKI_TYPELIST_3(CreateFunctor,int,int) >,
|
2005-10-06 17:50:51 +00:00
|
|
|
#else
|
2005-11-01 11:38:19 +00:00
|
|
|
Factory< AbstractProduct, int,Seq<CreateFunctor,int,int> >,
|
2005-10-06 17:50:51 +00:00
|
|
|
#endif
|
2005-11-07 12:06:43 +00:00
|
|
|
CreateUsingNew,
|
|
|
|
Loki::LongevityLifetime::DieAsSmallObjectChild
|
2005-07-28 14:27:12 +00:00
|
|
|
>
|
|
|
|
PFactoryFunctorParm;
|
|
|
|
|
|
|
|
Product* createProductRuntime(CreateFunctor func, int a, int b)
|
|
|
|
{
|
|
|
|
Product *p = func( a, b );
|
|
|
|
cout << " called by createProductRuntime(CreateFunctor func, int a, int b) " << endl;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Register creator functions
|
|
|
|
// No additional typdefs are necessary!
|
|
|
|
//////////////////////////////////////
|
|
|
|
|
2005-11-12 16:52:36 +00:00
|
|
|
Creator creator;
|
|
|
|
AbstractCreator* c = &creator;
|
2005-07-28 14:27:12 +00:00
|
|
|
CreatorT<Product> cT;
|
|
|
|
|
|
|
|
bool reg()
|
|
|
|
{
|
|
|
|
bool const ok1 = PFactoryNull::Instance().Register( 1, createProductNull );
|
2006-01-19 23:11:57 +00:00
|
|
|
bool const ok2 = PFactoryNull::Instance().Register( 2, static_cast<Product*(*)()>(createProductOver) );
|
2005-07-28 14:27:12 +00:00
|
|
|
bool const ok3 = PFactoryNull::Instance().Register( 3, c, &AbstractCreator::create );
|
|
|
|
bool const ok4 = PFactoryNull::Instance().Register( 4, &cT, &CreatorT<Product>::create );
|
|
|
|
|
2005-11-12 16:52:36 +00:00
|
|
|
bool const ok5 = PFactory::Instance().Register( "One", createProductParm );
|
2006-01-19 23:11:57 +00:00
|
|
|
bool const ok6 = PFactory::Instance().Register( "Two", static_cast<Product*(*)(int,int)>(createProductOver) );
|
2005-11-12 16:52:36 +00:00
|
|
|
bool const ok7 = PFactory::Instance().Register( "Three", c, &AbstractCreator::createParm );
|
|
|
|
bool const ok8 = PFactory::Instance().Register( "Four", &cT, &CreatorT<Product>::createParm );
|
2005-07-28 14:27:12 +00:00
|
|
|
|
|
|
|
bool const ok9 = PFactoryFunctorParm::Instance().Register( 1, createProductRuntime );
|
|
|
|
|
|
|
|
return ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 && ok9;
|
|
|
|
}
|
2005-11-12 16:52:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// detect memory leaks on MSVC Ide
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//#define MSVC_DETECT_MEMORY_LEAKS
|
|
|
|
#ifdef MSVC_DETECT_MEMORY_LEAKS
|
|
|
|
|
|
|
|
#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 );
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
void heap_debug()
|
|
|
|
{}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int main()
|
2005-07-28 14:27:12 +00:00
|
|
|
{
|
2006-01-09 07:27:01 +00:00
|
|
|
heap_debug();
|
2005-11-12 16:52:36 +00:00
|
|
|
|
2005-07-28 14:27:12 +00:00
|
|
|
reg();
|
|
|
|
|
2005-11-12 16:52:36 +00:00
|
|
|
AbstractProduct* p;
|
2005-07-28 14:27:12 +00:00
|
|
|
|
|
|
|
cout << endl << "creator function is a simple function:" << endl;
|
|
|
|
p= PFactoryNull::Instance().CreateObject( 1 );
|
|
|
|
delete p;
|
2005-11-12 16:52:36 +00:00
|
|
|
p= PFactory::Instance().CreateObject( "One", 64,64 );
|
2005-07-28 14:27:12 +00:00
|
|
|
delete p;
|
|
|
|
|
|
|
|
cout << endl << "creator function is a overloaded function:" << endl;
|
|
|
|
p= PFactoryNull::Instance().CreateObject( 2 );
|
|
|
|
delete p;
|
2005-11-12 16:52:36 +00:00
|
|
|
p= PFactory::Instance().CreateObject( "Two", 64,64 );
|
2005-07-28 14:27:12 +00:00
|
|
|
delete p;
|
|
|
|
|
|
|
|
cout << endl << "creator function is a member function:" << endl;
|
|
|
|
p= PFactoryNull::Instance().CreateObject( 3 );
|
|
|
|
delete p;
|
2005-11-12 16:52:36 +00:00
|
|
|
p= PFactory::Instance().CreateObject( "Three", 64,64 );
|
2005-07-28 14:27:12 +00:00
|
|
|
delete p;
|
|
|
|
|
|
|
|
cout << endl << "creator function is a template member function" << endl;
|
|
|
|
p= PFactoryNull::Instance().CreateObject( 4 );
|
|
|
|
delete p;
|
2005-11-12 16:52:36 +00:00
|
|
|
p= PFactory::Instance().CreateObject( "Four", 64,64 );
|
2005-07-28 14:27:12 +00:00
|
|
|
delete p;
|
|
|
|
|
|
|
|
CreateFunctor func1(createProductParm);
|
|
|
|
CreateFunctor func2(&cT, &CreatorT<Product>::createParm);
|
|
|
|
cout << endl << "creator function is a functor parameter" << endl;
|
|
|
|
p= PFactoryFunctorParm::Instance().CreateObject( 1, func1, 64,64 );
|
|
|
|
delete p;
|
|
|
|
p= PFactoryFunctorParm::Instance().CreateObject( 1, func2, 64,64 );
|
|
|
|
delete p;
|
2005-11-12 16:52:36 +00:00
|
|
|
|
2006-01-09 07:27:01 +00:00
|
|
|
|
2005-11-12 16:52:36 +00:00
|
|
|
cout << endl;
|
2006-01-09 07:27:01 +00:00
|
|
|
cout << "Registered ids: \n";
|
2005-11-12 16:52:36 +00:00
|
|
|
|
2006-01-09 07:27:01 +00:00
|
|
|
std::vector<std::string> ids = PFactory::Instance().RegisteredIds();
|
2005-11-12 16:52:36 +00:00
|
|
|
|
2006-01-09 07:27:01 +00:00
|
|
|
for(std::vector<std::string>::iterator it=ids.begin(); it!=ids.end(); ++it)
|
|
|
|
cout << *it << "\n";
|
2005-11-12 16:52:36 +00:00
|
|
|
|
|
|
|
|
2005-07-28 14:27:12 +00:00
|
|
|
cout << endl;
|
|
|
|
cout << endl;
|
2006-01-04 23:54:30 +00:00
|
|
|
|
|
|
|
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
2005-07-28 14:27:12 +00:00
|
|
|
system("PAUSE");
|
2006-01-04 23:54:30 +00:00
|
|
|
#endif
|
2005-11-12 16:52:36 +00:00
|
|
|
|
2005-07-28 14:27:12 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|