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.
////////////////////////////////////////////////////////////////////////////////
// $Header$
//#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 ) ;
bool const ok2 = PFactoryNull : : Instance ( ) . Register ( 2 , ( Product * ( * ) ( ) ) createProductOver ) ;
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 ) ;
bool const ok6 = PFactory : : Instance ( ) . Register ( " Two " , ( Product * ( * ) ( int , int ) ) createProductOver ) ;
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
{
2005-11-12 16:52:36 +00:00
heap_debug ( ) ;
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
cout < < endl ;
cout < < " Registered ids: \n " ;
std : : vector < std : : string > ids = PFactory : : Instance ( ) . RegisteredIds ( ) ;
for ( std : : vector < std : : string > : : iterator it = ids . begin ( ) ; it ! = ids . end ( ) ; + + it )
cout < < * it < < " \n " ;
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 ;
}
2005-11-12 16:52:36 +00:00
2005-07-28 14:27:12 +00:00
// $Log$
2006-01-05 00:23:44 +00:00
// Revision 1.12 2006/01/05 00:23:43 syntheticpp
// always use #include <loki/...>, Thanks to Lukas Fittl
//
2006-01-04 23:54:30 +00:00
// Revision 1.11 2006/01/04 23:54:28 syntheticpp
// remove system(PAUSE) for gcc, Thanks to Lukas Fittl
//
2006-01-04 23:45:08 +00:00
// Revision 1.10 2006/01/04 23:45:08 syntheticpp
// remove gcc 4.0 warnings, Thanks to Lukas Fittl
//
2005-11-12 16:52:36 +00:00
// Revision 1.9 2005/11/12 16:52:36 syntheticpp
// protect private data, add std::vector<IdType> RegisteredIds()
//
2005-11-07 12:06:43 +00:00
// Revision 1.8 2005/11/07 12:06:43 syntheticpp
// change lifetime policy DieOrder to a msvc7.1 compilable version. Make this the default lifetime for SmallObject
//
2005-11-05 17:43:55 +00:00
// Revision 1.7 2005/11/05 17:43:55 syntheticpp
// disable FollowIntoDeath/DieOrder lifetime policies when using the msvc 7.1 compiler, bug article: 839821 'Microsoft has confirmed that this is a problem..'
//
2005-11-01 11:38:19 +00:00
// Revision 1.6 2005/11/01 11:38:19 syntheticpp
// apply new lifetime policy to avoid crash on exit in test/Factory
//
2005-10-30 14:03:23 +00:00
// Revision 1.5 2005/10/30 14:03:23 syntheticpp
// replace tabs space
//
2005-10-30 13:49:44 +00:00
// Revision 1.4 2005/10/30 13:49:44 syntheticpp
// make disabling the TYPELIST macros possible
//
2005-10-06 17:50:51 +00:00
// Revision 1.3 2005/10/06 17:50:14 syntheticpp
// adding template based list/sequence implementation, should replace LOKI_TYPELIST_, update some files
//
2005-09-26 07:33:05 +00:00
// Revision 1.2 2005/09/26 07:33:05 syntheticpp
// move macros into LOKI_ namespace
//
2005-09-24 16:11:08 +00:00
// Revision 1.1 2005/09/24 16:10:14 syntheticpp
// move Factory example
//
2005-07-28 14:27:12 +00:00
// Revision 1.1 2005/07/28 14:27:12 syntheticpp
// add Factory example
//